Subversion Repositories ngs

Rev

Rev 3 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. // part of NeoGS project (c) 2007-2008 NedoPC
  2. //
  3.  
  4. // ports $00-$3f are in FPGA, $40-$ff are in CPLD
  5.  
  6. module ports(
  7.  
  8.         din,  // NGS z80 cpu DATA BUS inputs
  9.         dout, // NGS z80 cpu DATA BUS outputs
  10.         busin, // direction of bus: =1 - input, =0 - output
  11.         a, // NSG z80 cpu ADDRESS BUS
  12.  
  13.         iorq_n,mreq_n,rd_n,wr_n, // NGS z80 cpu control signals
  14.  
  15.  
  16.         data_port_input, // data_port input from zxbus module (async)
  17.         data_port_output, // data_port output to zxbus module (async to zxbus, sync here)
  18.         command_port_input, // command_port input from zxbus (async)
  19.  
  20.         data_bit_input, // data_bit from zxbus module (sync)
  21.         command_bit_input, // --//-- (sync)
  22.  
  23.         data_bit_output, // output to zxbus module
  24.         command_bit_output,
  25.  
  26.         data_bit_wr, // strobes (positive) to zxbus module, synchronous
  27.         command_bit_wr,
  28.  
  29.  
  30.         mode_8chans, // mode outputs for sound_main module
  31.         mode_pan4ch, //
  32.  
  33.         mode_ramro, // mode outputs for memmap module
  34.         mode_norom,
  35.  
  36.         mode_pg0, // page registers for memmap module
  37.         mode_pg1,
  38.  
  39.  
  40.         clksel0, // clock select (output from FPGA)
  41.         clksel1,
  42.  
  43.  
  44.         snd_wrtoggle, // toggle to write sound data to sound system memory
  45.         snd_datnvol,  // whether it's for volume (=0) or for samples (=1)
  46.         snd_addr,     // address: which channel to be written (0-7)
  47.         snd_data,     // actual 8-bit data to be written
  48.  
  49.  
  50.         md_din, // mp3 data interface
  51.         md_start,
  52.         md_dreq,
  53.         md_halfspeed,
  54.  
  55.         mc_ncs, // mp3 control interface
  56.         mc_xrst,
  57.         mc_dout,
  58.         mc_din,
  59.         mc_start,
  60.         mc_speed,
  61.         mc_rdy,
  62.  
  63.         sd_ncs, // SD card interface
  64.         sd_dout,
  65.         sd_din,
  66.         sd_start,
  67.         sd_det,
  68.         sd_wp,
  69.  
  70.         led, // LED control
  71.         led_toggle,
  72.  
  73.  
  74.         rst_n,
  75.  
  76.         cpu_clock // Z80 CPU clock (clk_fpga on schematics)
  77. );
  78.  
  79.  
  80.         localparam MPAG      = 6'h00;
  81.         localparam MPAGEX    = 6'h10;
  82.  
  83.         localparam ZXCMD     = 6'h01;
  84.         localparam ZXDATRD   = 6'h02;
  85.         localparam ZXDATWR   = 6'h03;
  86.         localparam ZXSTAT    = 6'h04;
  87.         localparam CLRCBIT   = 6'h05;
  88.  
  89.         localparam VOL1      = 6'h06;
  90.         localparam VOL2      = 6'h07;
  91.         localparam VOL3      = 6'h08;
  92.         localparam VOL4      = 6'h09;
  93.         localparam VOL5      = 6'h16;
  94.         localparam VOL6      = 6'h17;
  95.         localparam VOL7      = 6'h18;
  96.         localparam VOL8      = 6'h19;
  97.  
  98.         localparam DAMNPORT1 = 6'h0a;
  99.         localparam DAMNPORT2 = 6'h0b;
  100.  
  101.         localparam LEDCTR    = 6'h01;
  102.  
  103.         localparam GSCFG0    = 6'h0f;
  104.  
  105.         localparam SCTRL     = 6'h11;
  106.         localparam SSTAT     = 6'h12;
  107.  
  108.         localparam SD_SEND   = 6'h13;
  109.         localparam SD_READ   = 6'h13;
  110.         localparam SD_RSTR   = 6'h14;
  111.  
  112.         localparam MD_SEND   = 6'h14; // same as SD_RSTR!!!
  113.  
  114.         localparam MC_SEND   = 6'h15;
  115.         localparam MC_READ   = 6'h15;
  116.  
  117.  
  118.  
  119.         // inputs/outputs description
  120.  
  121.         input      [7:0] din;
  122.         output reg [7:0] dout;
  123.  
  124.         output reg busin; // =1 - dbus ins, =0 - dbus outs
  125.  
  126.         input [15:0] a;
  127.  
  128.         input iorq_n,mreq_n,rd_n,wr_n;
  129.  
  130.         input      [7:0] data_port_input;
  131.         input      [7:0] command_port_input;
  132.         output reg [7:0] data_port_output;
  133.  
  134.         input data_bit_input;
  135.         input command_bit_input;
  136.  
  137.         output reg data_bit_output;
  138.  
  139.         output reg command_bit_output;
  140.  
  141.         output reg data_bit_wr;
  142.  
  143.         output reg command_bit_wr;
  144.  
  145.         output reg mode_8chans;
  146.  
  147.         output reg mode_pan4ch;
  148.  
  149.         output reg mode_ramro;
  150.  
  151.         output reg mode_norom;
  152.  
  153.         output reg [6:0] mode_pg0;
  154.         output reg [6:0] mode_pg1;
  155.  
  156.         output reg clksel0;
  157.         output reg clksel1;
  158.  
  159.  
  160.         output reg snd_wrtoggle;
  161.         output reg snd_datnvol;
  162.         output reg [2:0] snd_addr;
  163.         output reg [7:0] snd_data;
  164.  
  165.  
  166.         input rst_n;
  167.  
  168.         input cpu_clock;
  169.  
  170.  
  171.  
  172.  
  173.         // SPI interfaces related
  174.  
  175.         // MP3 data interface
  176.         output [7:0] md_din; // data to MP3 data SPI interface
  177.  
  178.         output md_start; // start toggle for mp3 data spi
  179.  
  180.         input md_dreq; // data request from mp3 decoder
  181.  
  182.         output reg md_halfspeed;
  183.  
  184.  
  185.         // MP3 control interface
  186.         output reg mc_ncs; // nCS signal
  187.  
  188.         output reg mc_xrst; // xRESET signal
  189.  
  190.         output mc_start; // start toggle
  191.  
  192.         output reg [1:0] mc_speed;
  193.        
  194.         input mc_rdy;
  195.  
  196.         output [7:0] mc_din; // data to send
  197.  
  198.         input [7:0] mc_dout; // received data
  199.  
  200.  
  201.       // SDcard interface
  202.         output reg sd_ncs;
  203.  
  204.         output sd_start;
  205.  
  206.         output [7:0] sd_din;
  207.  
  208.         input [7:0] sd_dout;
  209.  
  210.         input sd_det;
  211.  
  212.         input sd_wp;
  213.  
  214.  
  215. // LED control register
  216.  
  217.         output reg led;
  218.         input led_toggle;
  219.  
  220.  
  221.  
  222. // internal regs & wires
  223.  
  224.         reg mode_expag; // extended paging mode register
  225.  
  226.         reg port09_bit5;
  227.  
  228.         wire port_enabled; // =1 when port address is in enabled region ($00-$3f)
  229.         wire mem_enabled; // =1 when memory mapped sound regs are addressed ($6000-$7FFF)
  230.         reg volports_enabled; // when volume ports are addressed (6-9 and $16-$19)
  231.  
  232.         reg iowrn_reg; // registered io write signal (all positive edge!)
  233.         reg iordn_reg; // --//--
  234.         reg merdn_reg; // --//--
  235.  
  236.  
  237.         reg port_wr; // synchronous positive write pulse (write from z80 to fpga regs)
  238.         reg port_rd;  // synchronous positive read pulse (read done from fpga regs to z80)
  239.  
  240.         reg memreg_rd; // when memory-mapped sound regs are read
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.         wire port00_wr;   // specific write and read strobes (1 clock cycle long positive)
  248.         wire p_ledctr_wr;
  249.         wire port02_rd;
  250.         wire port03_wr;
  251.         wire port05_wrrd;
  252.         wire port09_wr;
  253.         wire port0a_wrrd;
  254.         wire port0b_wrrd;
  255.         wire port0f_wr;
  256.         wire port10_wr;
  257.  
  258.         wire p_sstat_rd;
  259.         wire p_sctrl_rd;
  260.         wire p_sctrl_wr;
  261.         wire p_sdsnd_wr;
  262.         wire p_sdrd_rd;
  263.         wire p_sdrst_rd;
  264.         wire p_mdsnd_wr;
  265.         wire p_mcsnd_wr;
  266.         wire p_mcrd_rd;
  267.  
  268.         reg [2:0] volnum; // volume register number from port address
  269.  
  270.  
  271.  
  272.  
  273. // actual code
  274.  
  275.         //enabled ports
  276.         assign port_enabled = ~(a[7] | a[6]); // $00-$3F
  277.  
  278.         //enabled mem
  279.         assign mem_enabled = (~a[15]) & a[14] & a[13]; // $6000-$7FFF
  280.  
  281.         // volume ports enabled
  282.         always @*
  283.         begin
  284.                 if( a[5:0]==VOL1 ||
  285.                     a[5:0]==VOL2 ||
  286.                     a[5:0]==VOL3 ||
  287.                     a[5:0]==VOL4 ||
  288.                     a[5:0]==VOL5 ||
  289.                     a[5:0]==VOL6 ||
  290.                     a[5:0]==VOL7 ||
  291.                     a[5:0]==VOL8 )
  292.  
  293.                         volports_enabled <= 1'b1;
  294.                 else
  295.                         volports_enabled <= 1'b0;
  296.         end
  297.  
  298.  
  299.  
  300.         //when data bus outputs
  301.         always @*
  302.         begin
  303.                 if( port_enabled && (!iorq_n) && (!rd_n) )
  304.                         busin <= 1'b0; // bus outputs
  305.                 else
  306.                         busin <= 1'b1; // bus inputs
  307.         end
  308.  
  309.  
  310.  
  311.         // rd/wr/iorq syncing in and pulses
  312.         always @(posedge cpu_clock)
  313.         begin
  314.                 iowrn_reg <= iorq_n | wr_n;
  315.                 iordn_reg <= iorq_n | rd_n;
  316.  
  317.                 if( port_enabled && (!iorq_n) && (!wr_n) && iowrn_reg )
  318.                         port_wr <= 1'b1;
  319.                 else
  320.                         port_wr <= 1'b0;
  321.  
  322.                 if( port_enabled && (!iorq_n) && (!rd_n) && iordn_reg )
  323.                         port_rd <= 1'b1;
  324.                 else
  325.                         port_rd <= 1'b0;
  326.  
  327.         end
  328.  
  329.         // mreq syncing and mem read pulse
  330.         always @(negedge cpu_clock)
  331.         begin
  332.                 merdn_reg <= mreq_n | rd_n;
  333.  
  334.                 if( mem_enabled && (!mreq_n) && (!rd_n) && merdn_reg )
  335.                         memreg_rd <= 1'b1;
  336.                 else
  337.                         memreg_rd <= 1'b0;
  338.  
  339.         end
  340.  
  341.  
  342.         // specific ports strobes
  343.         assign port00_wr   = ( a[5:0]==MPAG      && port_wr            );
  344.         assign port02_rd   = ( a[5:0]==ZXDATRD   && port_rd            );
  345.         assign port03_wr   = ( a[5:0]==ZXDATWR   && port_wr            );
  346.         assign port05_wrrd = ( a[5:0]==CLRCBIT   && (port_wr||port_rd) );
  347.         assign port09_wr   = ( a[5:0]==VOL4      && port_wr            );
  348.         assign port0a_wrrd = ( a[5:0]==DAMNPORT1 && (port_wr||port_rd) );
  349.         assign port0b_wrrd = ( a[5:0]==DAMNPORT2 && (port_wr||port_rd) );
  350.         assign port0f_wr   = ( a[5:0]==GSCFG0    && port_wr            );
  351.         assign port10_wr   = ( a[5:0]==MPAGEX    && port_wr            );
  352.  
  353.  
  354.         assign p_sctrl_rd = ( a[5:0]==SCTRL  && port_rd );
  355.         assign p_sctrl_wr = ( a[5:0]==SCTRL  && port_wr );
  356.         assign p_sstat_rd = ( a[5:0]==SSTAT  && port_rd );
  357.         assign p_sdsnd_wr = ( a[5:0]==SD_SEND && port_wr );
  358.         assign p_sdrd_rd  = ( a[5:0]==SD_READ && port_rd );
  359.         assign p_sdrst_rd = ( a[5:0]==SD_RSTR && port_rd );
  360.         assign p_mdsnd_wr = ( a[5:0]==MD_SEND && port_wr );
  361.         assign p_mcsnd_wr = ( a[5:0]==MC_SEND && port_wr );
  362.         assign p_mcrd_rd  = ( a[5:0]==MC_READ && port_rd );
  363.  
  364.         assign p_ledctr_wr = ( a[5:0]==LEDCTR && port_wr );
  365.  
  366.  
  367.  
  368.         // read from fpga to Z80
  369.         always @*
  370.         begin
  371.                 case( a[5:0] )
  372.                 ZXCMD: // command register
  373.                         dout <= command_port_input;
  374.                 ZXDATRD: // data register
  375.                         dout <= data_port_input;
  376.                 ZXSTAT: // status bits
  377.                         dout <= { data_bit_input, 6'bXXXXXX, command_bit_input };
  378.                 GSCFG0: // config register #0F
  379.                         dout <= { 1'b0, mode_pan4ch, clksel1, clksel0, mode_expag, mode_8chans, mode_ramro, mode_norom };
  380.  
  381.                 SSTAT:
  382.                         dout <= { 4'd0, mc_rdy, sd_wp, sd_det, md_dreq };
  383.                 SCTRL:
  384.                         dout <= { 2'd0, mc_speed[1], md_halfspeed, mc_speed[0], mc_xrst, mc_ncs, sd_ncs };
  385.                 SD_READ:
  386.                         dout <= sd_dout;
  387.                 SD_RSTR:
  388.                         dout <= sd_dout;
  389.                 MC_READ:
  390.                         dout <= mc_dout;
  391.  
  392.                 default:
  393.                         dout <= 8'bXXXXXXXX;
  394.                 endcase
  395.         end
  396.  
  397.  
  398.  
  399.  
  400.  
  401.         // write to $00 and $10 ports ++
  402.         always @(posedge cpu_clock)
  403.         begin
  404.                 if( port00_wr==1'b1 ) // port 00
  405.                 begin
  406.                         if( mode_expag==1'b0 ) // normal paging
  407.                                 mode_pg0[6:0] <= { din[5:0], 1'b0 };
  408.                         else // extended paging
  409.                                 mode_pg0[6:0] <= { din[5:0], din[7] };
  410.                 end
  411.  
  412.                 if( mode_expag==1'b0 && port00_wr==1'b1 ) // port 10 (when in normal mode, part of port 00)
  413.                         mode_pg1[6:0] <= { din[5:0], 1'b1 };
  414.                 else if( mode_expag==1'b1 && port10_wr==1'b1 )
  415.                         mode_pg1[6:0] <= { din[5:0], din[7] };
  416.         end
  417.  
  418.         // port $03 write ++
  419.         always @(posedge cpu_clock)
  420.         begin
  421.                 if( port03_wr==1'b1 )
  422.                         data_port_output <= din;
  423.         end
  424.  
  425.         // port $09 bit tracing
  426.         always @(posedge cpu_clock)
  427.         begin
  428.                 if( port09_wr==1'b1 )
  429.                         port09_bit5 <= din[5];
  430.         end
  431.  
  432.         // write and reset of port $0F ++
  433.         always @(posedge cpu_clock,negedge rst_n)
  434.         begin
  435.                 if( rst_n==1'b0 ) // reset!
  436.                         { mode_pan4ch, clksel1, clksel0, mode_expag, mode_8chans, mode_ramro, mode_norom } <= 7'b0110000;
  437.                 else // write to port
  438.                 begin
  439.                         if( port0f_wr == 1'b1 )
  440.                         begin
  441.                                 { mode_pan4ch, clksel1, clksel0, mode_expag, mode_8chans, mode_ramro, mode_norom } <= din[6:0];
  442.                         end
  443.                 end
  444.         end
  445.  
  446.         // data bit handling
  447.     always @*
  448.     begin
  449.                 case( {port02_rd,port03_wr,port0a_wrrd} )
  450.                 3'b100:
  451.                 begin
  452.                         data_bit_output <= 1'b0;
  453.                         data_bit_wr <= 1'b1;
  454.                 end
  455.  
  456.                 3'b010:
  457.                 begin
  458.                         data_bit_output <= 1'b1; // ++
  459.                         data_bit_wr <= 1'b1;
  460.                 end
  461.  
  462.                 3'b001:
  463.                 begin
  464.                         data_bit_output <= ~mode_pg0[0];
  465.                         data_bit_wr <= 1'b1;
  466.                 end
  467.  
  468.                 default:
  469.                 begin
  470.                         data_bit_output <= 1'bX;
  471.                         data_bit_wr <= 1'b0;
  472.                 end
  473.         endcase
  474.  
  475.     end
  476.  
  477.         // command bit handling
  478.         always @*
  479.         begin
  480.                 casex( {port05_wrrd,port0b_wrrd} )
  481.                 2'b10:
  482.                 begin
  483.                         command_bit_output <= 1'b0;
  484.                         command_bit_wr <= 1'b1;
  485.                 end
  486.  
  487.                 2'b01:
  488.                 begin
  489.                         command_bit_output <= port09_bit5;
  490.                         command_bit_wr <= 1'b1;
  491.                 end
  492.  
  493.                 default:
  494.                 begin
  495.                         command_bit_output <= 1'bX;
  496.                         command_bit_wr <= 1'b0;
  497.                 end
  498.                 endcase
  499.         end
  500.  
  501.         // handle data going to sound module (volume and samples values)
  502.         always @*
  503.         begin
  504.                 case( a[5:0] ) // port addresses to volume register numbers
  505.                 VOL1:
  506.                         volnum <= 3'd0;
  507.                 VOL2:
  508.                         volnum <= 3'd1;
  509.                 VOL3:
  510.                         volnum <= 3'd2;
  511.                 VOL4:
  512.                         volnum <= 3'd3;
  513.                 VOL5:
  514.                         volnum <= 3'd4;
  515.                 VOL6:
  516.                         volnum <= 3'd5;
  517.                 VOL7:
  518.                         volnum <= 3'd6;
  519.                 VOL8:
  520.                         volnum <= 3'd7;
  521.                 default:
  522.                         volnum <= 3'bXXX;
  523.                 endcase
  524.         end
  525.  
  526.         // handling itself (sending data to sound module)
  527.         always @(posedge cpu_clock)
  528.         begin
  529.                 if( memreg_rd ) // memory read - sample data write
  530.                 begin
  531.                         snd_wrtoggle <= ~snd_wrtoggle;
  532.                         snd_datnvol  <= 1'b1; // sample data
  533.  
  534.                         if( !mode_8chans ) // 4 channel mode
  535.                                 snd_addr <= { 1'b0, a[9:8] };
  536.                         else // 8 channel mode
  537.                                 snd_addr <= a[10:8];
  538.  
  539.                         snd_data <= din;
  540.                 end
  541.                 else if( volports_enabled && port_wr )
  542.                 begin
  543.                         snd_wrtoggle <= ~snd_wrtoggle;
  544.                         snd_datnvol  <= 1'b0; // volume data
  545.                         snd_addr <= volnum;
  546.                         snd_data <= din;
  547.                 end
  548.         end
  549.  
  550.  
  551.  
  552.  
  553.  
  554.  
  555.         //SPI (mp3, SD) interfaces
  556.  
  557.         assign sd_din = (a[5:0]==SD_RSTR) ? 8'hFF : din;
  558.         assign mc_din = din;
  559.         assign md_din = din;
  560.  
  561.  
  562.         assign sd_start = p_sdsnd_wr | p_sdrst_rd;
  563.         assign mc_start = p_mcsnd_wr;
  564.         assign md_start = p_mdsnd_wr;
  565.  
  566.  
  567.       always @(posedge cpu_clock, negedge rst_n)
  568.       begin
  569.                 if( !rst_n ) // async reset
  570.                 begin
  571.                         md_halfspeed <= 1'b0;
  572.                         mc_speed     <= 2'b01;
  573.                         mc_xrst      <= 1'b0;
  574.                         mc_ncs       <= 1'b1;
  575.                         sd_ncs       <= 1'b1;
  576.                 end
  577.                 else // clock
  578.                 begin
  579.                         if( p_sctrl_wr )
  580.                         begin
  581.                                 if( din[0] )
  582.                                         sd_ncs       <= din[7];
  583.  
  584.                                 if( din[1] )
  585.                                         mc_ncs       <= din[7];
  586.  
  587.                                 if( din[2] )
  588.                                         mc_xrst      <= din[7];
  589.  
  590.                                 if( din[3] )
  591.                                         mc_speed[0]  <= din[7];
  592.  
  593.                                 if( din[4] )
  594.                                         md_halfspeed <= din[7];
  595.                                
  596.                                 if( din[5] )
  597.                                         mc_speed[1]  <= din[7];
  598.  
  599.                         end
  600.                 end
  601.       end
  602.  
  603.  
  604.  
  605.         // LED control
  606.         always @(posedge cpu_clock, negedge rst_n)
  607.         begin
  608.                 if( !rst_n )
  609.                         led <= 1'b0;
  610.                 else
  611.                 begin
  612.                         if( p_ledctr_wr )
  613.                                 led <= din[0];
  614.                         else if( led_toggle )
  615.                                 led <= ~led;
  616.                 end
  617.  
  618.         end
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625. endmodule
  626.  
  627.