Subversion Repositories zxusbnet

Rev

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

  1. // ZXiznet project
  2. // (c) NedoPC 2012
  3. //
  4. // zx-bus functions: ports mapping/access, ROM mapping
  5.  
  6. module zbus
  7. (
  8.         input  wire        fclk,
  9.  
  10.         input  wire [15:0] za,
  11.         inout  wire [ 7:0] zd,
  12.         //
  13.         inout  wire [ 7:0] bd,
  14.         //
  15.         input  wire        ziorq_n,
  16.         input  wire        zrd_n,
  17.         input  wire        zwr_n,
  18.         input  wire        zmreq_n,
  19.         output wire        ziorqge,
  20.         output wire        zblkrom,
  21.         input  wire        zcsrom_n,
  22.         input  wire        zrst_n,
  23.  
  24.         //
  25.         output wire        ports_wrena,
  26.         output wire        ports_wrstb_n,
  27.         output wire [ 1:0] ports_addr,
  28.         output wire [ 7:0] ports_wrdata,
  29.         input  wire [ 7:0] ports_rddata,
  30.        
  31.         //
  32.         input  wire [ 1:0] rommap_win,
  33.         input  wire        rommap_ena,
  34.  
  35.         //
  36.         output reg         sl811_cs_n,
  37.         output reg         sl811_a0,
  38.  
  39.         //
  40.         output reg         w5300_cs_n,
  41.         input  wire        w5300_ports,
  42.         input  wire [ 9:0] async_w5300_addr,
  43.         output reg  [ 9:0] w5300_addr,
  44.  
  45.  
  46.  
  47.         // buffered rd/wr strobes to usb/ether chips
  48.         output reg         bwr_n,
  49.         output reg         brd_n
  50. );
  51.         parameter BASE_ADDR = 8'hAB;
  52.  
  53.  
  54.  
  55.  
  56.         reg [1:0] rst_n_resync;
  57.         wire rst_n = rst_n_resync[1];
  58.  
  59.  
  60.         wire io_addr_ok;
  61.  
  62.         wire mrd, mwr;
  63.  
  64.         wire ena_dbuf;
  65.         wire ena_din;
  66.         wire ena_dout;
  67.  
  68.  
  69.  
  70.         // buffering chipselects
  71.         reg async_w5300_cs_n;
  72.         reg async_sl811_cs_n;
  73.         //
  74.         reg [1:0] r_w5300_cs_n;
  75.         reg [1:0] r_sl811_cs_n;
  76.  
  77.         // buffering sl811 a0
  78.         reg async_sl811_a0;
  79.         //
  80.         reg [1:0] r_sl811_a0;
  81.  
  82.         // buffering w5300 address
  83.         reg [9:0] r_w5300_addr [0:1];
  84.  
  85.  
  86.         // for filtering strobes
  87.         reg [2:0] wr_regs;
  88.         reg [2:0] rd_regs;
  89.         reg       wr_state,
  90.                   rd_state;
  91.         wire      wr_start,
  92.                   rd_start;
  93.  
  94.         //
  95.         reg [2:0] ctr_5;
  96.  
  97.  
  98.  
  99.  
  100.         // common read and write latches latch
  101.         reg [7:0] read_latch;
  102.         reg [7:0] write_latch;
  103.  
  104.  
  105.  
  106.  
  107.         // reset resync
  108.         always @(posedge fclk, negedge zrst_n)
  109.         if( !zrst_n )
  110.                 rst_n_resync[1:0] <= 2'b00;
  111.         else
  112.                 rst_n_resync[1:0] <= { rst_n_resync[0], 1'b1 };
  113.  
  114.  
  115.  
  116.  
  117.         // make filtered out vesions of read/write strobes
  118.         always @(posedge fclk)
  119.         begin
  120.                 wr_regs[2:0] <= { wr_regs[1:0], ~zwr_n };
  121.                 rd_regs[2:0] <= { rd_regs[1:0], ~zrd_n };
  122.         end
  123.         //
  124.         always @(posedge fclk, negedge rst_n)
  125.         if( !rst_n )
  126.         begin
  127.                 wr_state <= 1'b0;
  128.                 rd_state <= 1'b0;
  129.         end
  130.         else
  131.         begin
  132.                      if( wr_regs[2:1]==2'b11 && !wr_state )
  133.                         wr_state <= 1'b1;
  134.                 else if( wr_regs[2:1]==2'b00 &&  wr_state )
  135.                         wr_state <= 1'b0;
  136.                 //
  137.                      if( rd_regs[2:1]==2'b11 && !rd_state )
  138.                         rd_state <= 1'b1;
  139.                 else if( rd_regs[2:1]==2'b00 &&  rd_state )
  140.                         rd_state <= 1'b0;
  141.         end
  142.         //
  143.         assign wr_start = wr_regs[2:1]==2'b11 && !wr_state;
  144.         assign rd_start = rd_regs[2:1]==2'b11 && !rd_state;
  145.  
  146.  
  147.         // buffered rd/wrs
  148.         always @(posedge fclk)
  149.         begin
  150.                 if( wr_start )
  151.                         bwr_n <= 1'b0;
  152.                 else if( !ctr_5 )
  153.                         bwr_n <= 1'b1;
  154.                 //
  155.                 if( rd_start )
  156.                         brd_n <= 1'b0;
  157.                 else if( !ctr_5 )
  158.                         brd_n <= 1'b1;
  159.         end
  160.         //
  161.         always @(posedge fclk, negedge rst_n)
  162.         if( !rst_n )
  163.         begin
  164.                 ctr_5 <= 3'd0;
  165.         end
  166.         else if( wr_start || rd_start )
  167.                 ctr_5 <= 3'd4;
  168.         else
  169.                 ctr_5 <= ctr_5 - 3'd1;
  170.  
  171.  
  172.         // buffered chipselects
  173.         always @(posedge fclk)
  174.         begin
  175.                 r_w5300_cs_n[1:0] <= { r_w5300_cs_n[0], async_w5300_cs_n };
  176.                 r_sl811_cs_n[1:0] <= { r_sl811_cs_n[0], async_sl811_cs_n };
  177.         end
  178.         //
  179.         always @(posedge fclk)
  180.         if( wr_start || rd_start )
  181.         begin
  182.                 w5300_cs_n <= r_w5300_cs_n[1];
  183.                 sl811_cs_n <= r_sl811_cs_n[1];
  184.         end
  185.         else if( !ctr_5 )
  186.         begin
  187.                 w5300_cs_n <= 1'b1;
  188.                 sl811_cs_n <= 1'b1;
  189.         end
  190.  
  191.  
  192.         // buffered sl811_a0
  193.         always @(posedge fclk)
  194.                 r_sl811_a0[1:0] <= { r_sl811_a0[0], async_sl811_a0 };
  195.         //
  196.         always @(posedge fclk)
  197.         if( wr_start || rd_start )
  198.                 sl811_a0 <= r_sl811_a0[1];
  199.  
  200.  
  201.  
  202.         // buffered w5300_addr
  203.         always @(posedge fclk)
  204.         begin
  205.                 r_w5300_addr[0] <= async_w5300_addr;
  206.                 r_w5300_addr[1] <= r_w5300_addr[0];
  207.         end
  208.         //
  209.         always @(posedge fclk)
  210.         if( wr_start || rd_start )
  211.                 w5300_addr <= r_w5300_addr[1];
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.         // addr decode
  219.         assign io_addr_ok = (za[7:0]==BASE_ADDR);
  220.  
  221.  
  222.         // IORQGE
  223.         assign ziorqge = io_addr_ok ? 1'b1 : 1'bZ;
  224.  
  225.  
  226.  
  227.         // ports write
  228.         assign ports_addr = za[9:8];
  229.         //
  230.         assign ports_wrdata = zd;
  231.         //
  232.         assign ports_wrena   = io_addr_ok && za[15];
  233.         assign ports_wrstb_n = ziorq_n | zwr_n;
  234.  
  235.  
  236.  
  237.         always @*
  238.                 async_sl811_cs_n = !( !w5300_ports && io_addr_ok && ( !za[15] || (za[15] && za[9:8]==2'b00) ) && !ziorq_n );
  239.  
  240.         //
  241.         always @*
  242.                 async_sl811_a0 = ~za[15];
  243.  
  244.  
  245.         // w5300 chip select
  246.         assign mwr = !zmreq_n && !zwr_n && (za[15:14]==rommap_win) && rommap_ena;
  247.         assign mrd = !zmreq_n && !zrd_n && !zcsrom_n && (za[15:14]==rommap_win) && rommap_ena;
  248.         //
  249.         always @*
  250.                 async_w5300_cs_n = ~(mwr || mrd || ( w5300_ports && io_addr_ok && !za[15] && !ziorq_n ) );
  251.  
  252.         // block ROM
  253.         assign zblkrom = (rommap_ena && (za[15:14]==rommap_win)) ? 1'b1 : 1'bZ;
  254.  
  255.  
  256.  
  257.         assign ena_dbuf = (~async_sl811_cs_n) | (~async_w5300_cs_n);
  258.         assign ena_dout = ~zrd_n;
  259.  
  260.         wire ports_rd = io_addr_ok && !ziorq_n && !zrd_n && za[15] && (za[9:8]!=2'b00);
  261.  
  262.         wire b_ena_dbuf = (~sl811_cs_n) | (~w5300_cs_n);
  263.         wire b_ena_din  = ~bwr_n;
  264.  
  265.         // ports data read/buffering
  266. /*      assign zd = (io_addr_ok && !ziorq_n && !zrd_n && za[15] && (za[9:8]!=2'b00)) ?
  267.                     ports_rddata : ( (ena_dbuf && ena_dout) ? bd : 8'bZZZZ_ZZZZ );
  268.  
  269.  
  270.         assign bd = (ena_dbuf && ena_din) ? zd : 8'bZZZZ_ZZZZ;
  271. */
  272.  
  273.         assign zd = ports_rd ? ports_rddata : ((ena_dbuf && ena_dout) ? read_latch : 8'hZZ);
  274.  
  275.         assign bd = (b_ena_dbuf && b_ena_din) ? write_latch : 8'hZZ;
  276.  
  277.  
  278.  
  279.  
  280.         // write latch
  281.         always @*
  282.         if( !zwr_n )
  283.                 write_latch <= zd;
  284.  
  285.         // read latch
  286.         always @*
  287.         if( !brd_n )
  288.                 read_latch <= bd;
  289.  
  290.  
  291.  
  292.  
  293. endmodule
  294.  
  295.