Subversion Repositories zxusbnet

Rev

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

  1. // ZXiznet project
  2. // (c) NedoPC 2012-2018
  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|ziorq_n) };
  121.                 rd_regs[2:0] <= { rd_regs[1:0], ~(zrd_n|ziorq_n) };
  122.         end
  123.         //
  124.  
  125.         assign wr_start = wr_regs[2:0]==3'b001 && !ctr_5;
  126.         assign rd_start = rd_regs[2:0]==3'b001 && !ctr_5;
  127.  
  128.  
  129.         // buffered rd/wrs
  130.         always @(posedge fclk)
  131.         begin
  132.                 if( wr_start )
  133.                         bwr_n <= 1'b0;
  134.                 else if( !ctr_5 )
  135.                         bwr_n <= 1'b1;
  136.                 //
  137.                 if( rd_start )
  138.                         brd_n <= 1'b0;
  139.                 else if( !ctr_5 )
  140.                         brd_n <= 1'b1;
  141.         end
  142.         //
  143.         always @(posedge fclk, negedge rst_n)
  144.         if( !rst_n )
  145.         begin
  146.                 ctr_5 <= 3'd0;
  147.         end
  148.         else if( wr_start || rd_start )
  149.                 ctr_5 <= 3'd4;
  150.         else if( ctr_5 )
  151.                 ctr_5 <= ctr_5 - 3'd1;
  152.  
  153.  
  154.         // buffered chipselects
  155.         always @(posedge fclk)
  156.         begin
  157.                 r_w5300_cs_n[1:0] <= { r_w5300_cs_n[0], async_w5300_cs_n };
  158.                 r_sl811_cs_n[1:0] <= { r_sl811_cs_n[0], async_sl811_cs_n };
  159.         end
  160.         //
  161.         always @(posedge fclk)
  162.         if( wr_start || rd_start )
  163.         begin
  164.                 w5300_cs_n <= async_w5300_cs_n;
  165.                 sl811_cs_n <= async_sl811_cs_n;
  166.         end
  167.         else if( !ctr_5 )
  168.         begin
  169.                 w5300_cs_n <= 1'b1;
  170.                 sl811_cs_n <= 1'b1;
  171.         end
  172.  
  173.  
  174.         // buffered sl811_a0
  175.         always @(posedge fclk)
  176.                 r_sl811_a0[1:0] <= { r_sl811_a0[0], async_sl811_a0 };
  177.         //
  178.         always @(posedge fclk)
  179.         if( wr_start || rd_start )
  180.                 sl811_a0 <= async_sl811_a0;
  181.  
  182.  
  183.  
  184.         // buffered w5300_addr
  185.         always @(posedge fclk)
  186.         begin
  187.                 r_w5300_addr[0] <= async_w5300_addr;
  188.                 r_w5300_addr[1] <= r_w5300_addr[0];
  189.         end
  190.         //
  191.         always @(posedge fclk)
  192.         if( wr_start || rd_start )
  193.                 w5300_addr <= async_w5300_addr;
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.         // addr decode
  201.         assign io_addr_ok = (za[7:0]==BASE_ADDR);
  202.  
  203.  
  204.         // IORQGE
  205.         assign ziorqge = io_addr_ok ? 1'b1 : 1'bZ;
  206.  
  207.  
  208.  
  209.         // ports write
  210.         assign ports_addr = za[9:8];
  211.         //
  212.         assign ports_wrdata = zd;
  213.         //
  214.         assign ports_wrena   = io_addr_ok && za[15];
  215.         assign ports_wrstb_n = ziorq_n | zwr_n;
  216.  
  217.  
  218.  
  219.         always @*
  220.                 async_sl811_cs_n = !( !w5300_ports && io_addr_ok && ( !za[15] || (za[15] && za[9:8]==2'b00) ) && !ziorq_n );
  221.  
  222.         //
  223.         always @*
  224.                 async_sl811_a0 = ~za[15];
  225.  
  226.  
  227.         // w5300 chip select
  228.         assign mwr = 1'b0; // !zmreq_n && !zwr_n && (za[15:14]==rommap_win) && rommap_ena;
  229.         assign mrd = 1'b0; // !zmreq_n && !zrd_n && !zcsrom_n && (za[15:14]==rommap_win) && rommap_ena;
  230.         //
  231.         always @*
  232.                 async_w5300_cs_n = ~(mwr || mrd || ( w5300_ports && io_addr_ok && !za[15] && !ziorq_n ) );
  233.  
  234.         // block ROM
  235.         assign zblkrom = (rommap_ena && (za[15:14]==rommap_win)) ? 1'b1 : 1'bZ;
  236.  
  237.  
  238.  
  239.         assign ena_dbuf = (~async_sl811_cs_n) | (~async_w5300_cs_n);
  240.         assign ena_dout = ~zrd_n;
  241.  
  242.         wire ports_rd = io_addr_ok && !ziorq_n && !zrd_n && za[15] && (za[9:8]!=2'b00);
  243.  
  244.         wire b_ena_dbuf = (~sl811_cs_n) | (~w5300_cs_n);
  245.         wire b_ena_din  = ~bwr_n;
  246.  
  247.         // ports data read/buffering
  248. /*      assign zd = (io_addr_ok && !ziorq_n && !zrd_n && za[15] && (za[9:8]!=2'b00)) ?
  249.                     ports_rddata : ( (ena_dbuf && ena_dout) ? bd : 8'bZZZZ_ZZZZ );
  250.  
  251.  
  252.         assign bd = (ena_dbuf && ena_din) ? zd : 8'bZZZZ_ZZZZ;
  253. */
  254.  
  255.         assign zd = ports_rd ? ports_rddata : ((ena_dbuf && ena_dout) ? read_latch : 8'hZZ);
  256.  
  257.         assign bd = (b_ena_dbuf && b_ena_din) ? write_latch : 8'hZZ;
  258.  
  259.  
  260.  
  261.  
  262.         // write latch
  263.         always @*
  264.         if( !zwr_n )
  265.                 write_latch <= zd;
  266.  
  267.         // read latch
  268.         always @*
  269.         if( !brd_n )
  270.                 read_latch <= bd;
  271.  
  272.  
  273.  
  274.  
  275. endmodule
  276.  
  277.