Subversion Repositories pentevo

Rev

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

  1. // ZX-Evo Base Configuration (c) NedoPC 2008,2009,2010,2011,2012,2013,2014
  2. //
  3. // Z80 memory manager: routes ROM/RAM accesses, makes wait-states for 14MHz or stall condition, etc.
  4.  
  5. /*
  6.     This file is part of ZX-Evo Base Configuration firmware.
  7.  
  8.     ZX-Evo Base Configuration firmware is free software:
  9.     you can redistribute it and/or modify it under the terms of
  10.     the GNU General Public License as published by
  11.     the Free Software Foundation, either version 3 of the License, or
  12.     (at your option) any later version.
  13.  
  14.     ZX-Evo Base Configuration firmware is distributed in the hope that
  15.     it will be useful, but WITHOUT ANY WARRANTY; without even
  16.     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17.     See the GNU General Public License for more details.
  18.  
  19.     You should have received a copy of the GNU General Public License
  20.     along with ZX-Evo Base Configuration firmware.
  21.     If not, see <http://www.gnu.org/licenses/>.
  22. */
  23.  
  24. //
  25. // fclk    _/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\
  26. //          |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
  27. // zclk     /```\___/```\___/```\___/```````\_______/```````\_______/```````````````\_______________/```````````````\_______________/`
  28. //          |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
  29. // zpos     `\___/```\___/```\___/```\___________/```\___________/```\___________________________/```\___________________________/```\
  30. //          |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
  31. // zneg     _/```\___/```\___/```\_______/```\___________/```\___________________/```\___________________________/```\________________
  32.  
  33. `include "../include/tune.v"
  34.  
  35. module zmem(
  36.  
  37.         input  wire fclk,
  38.         input  wire rst_n,
  39.  
  40.         input  wire zpos, //
  41.         input  wire zneg, // strobes which show positive and negative edges of zclk
  42.  
  43.         input  wire cbeg,      // DRAM synchronization
  44.         input  wire post_cbeg, //
  45.         input  wire pre_cend,  //
  46.         input  wire cend,      //
  47.  
  48.  
  49.         input  wire [15:0] za,
  50.  
  51.         input  wire [ 7:0] zd_in, // won't emit anything to Z80 bus, data bus mux is another module
  52.         output wire [ 7:0] zd_out, // output to Z80 bus
  53.  
  54.         output wire zd_ena, // out bus to the Z80
  55.  
  56.         input  wire m1_n,
  57.         input  wire rfsh_n,
  58.         input  wire mreq_n,
  59.         input  wire iorq_n,
  60.         input  wire rd_n,
  61.         input  wire wr_n,
  62.  
  63.  
  64.         input  wire [ 1:0] int_turbo, // 2'b00 - 3.5,
  65.                                       // 2'b01 - 7.0,
  66.                                       // 2'b1x - 14.0
  67.  
  68.  
  69.  
  70.         input  wire        win0_romnram, // four windows, each 16k,
  71.         input  wire        win1_romnram, // ==1 - there is rom,
  72.         input  wire        win2_romnram, // ==0 - there is ram
  73.         input  wire        win3_romnram, //
  74.  
  75.         input  wire [ 7:0] win0_page, // which 16k page is in given window
  76.         input  wire [ 7:0] win1_page, //
  77.         input  wire [ 7:0] win2_page, //
  78.         input  wire [ 7:0] win3_page, //
  79.  
  80.         input  wire        win0_wrdisable, // ==1 - no write is possible to window
  81.         input  wire        win1_wrdisable,
  82.         input  wire        win2_wrdisable,
  83.         input  wire        win3_wrdisable,
  84.  
  85.  
  86.         input  wire        romrw_en,
  87.  
  88.  
  89.  
  90.         input  wire        nmi_buf_clr,
  91.  
  92.  
  93.  
  94.         output reg  [ 4:0] rompg, // output for ROM paging
  95.         output wire        romoe_n,
  96.         output wire        romwe_n,
  97.         output wire        csrom,
  98.  
  99.  
  100.         output wire        cpu_req,
  101.         output wire        cpu_rnw,
  102.         output wire [20:0] cpu_addr,
  103.         output wire [ 7:0] cpu_wrdata,
  104.         output wire        cpu_wrbsel,
  105.  
  106.         input  wire [15:0] cpu_rddata,
  107.  
  108.         input  wire        cpu_next,
  109.         input  wire        cpu_strobe,
  110.  
  111.  
  112.         output wire        cpu_stall // for zclock
  113.  
  114. );
  115.  
  116.  
  117.         wire [1:0] win;
  118.         reg [7:0] page;
  119.         reg romnram;
  120.         reg wrdisable;
  121.  
  122.  
  123.  
  124.         wire dram_beg;
  125.         wire opfetch, memrd, memwr;
  126.         wire stall14, stall7_35;
  127.  
  128.         wire stall14_ini;
  129.         wire stall14_cyc;
  130.         reg  stall14_cycrd;
  131.         reg  stall14_fin;
  132.  
  133.         reg r_mreq_n;
  134.  
  135.  
  136.         reg pending_cpu_req;
  137.  
  138.         reg cpu_rnw_r;
  139.  
  140.  
  141.  
  142.         // this is for 7/3.5mhz  
  143.         wire ramreq;
  144.         wire ramwr,ramrd;
  145.         wire cpureq_357;
  146.         reg ramrd_reg,ramwr_reg;
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.         // make paging
  154.         assign win[1:0] = za[15:14];
  155.  
  156.         always @*
  157.         case( win )
  158.                 2'b00: begin
  159.                         page      = win0_page;
  160.                         romnram   = win0_romnram;
  161.                         wrdisable = win0_wrdisable;
  162.                 end
  163.  
  164.                 2'b01: begin
  165.                         page      = win1_page;
  166.                         romnram   = win1_romnram;
  167.                         wrdisable = win1_wrdisable;
  168.                 end
  169.  
  170.                 2'b10: begin
  171.                         page      = win2_page;
  172.                         romnram   = win2_romnram;
  173.                         wrdisable = win2_wrdisable;
  174.                 end
  175.  
  176.                 2'b11: begin
  177.                         page      = win3_page;
  178.                         romnram   = win3_romnram;
  179.                         wrdisable = win3_wrdisable;
  180.                 end
  181.         endcase
  182.  
  183.  
  184.         // rom paging - only half a megabyte addressing.
  185.         always @*
  186.         begin
  187.                 rompg[4:0] = page[4:0];
  188.         end
  189.  
  190.  
  191.  
  192.  
  193.         assign romwe_n = wr_n | mreq_n | (~romrw_en) | wrdisable;
  194.         assign romoe_n = rd_n | mreq_n;
  195.  
  196.         assign csrom = romnram; // positive polarity!
  197.  
  198.  
  199.  
  200.         // 7/3.5mhz support
  201.  
  202.         assign ramreq = (~mreq_n) && (~romnram) && rfsh_n;
  203.         assign ramrd = ramreq & (~rd_n);
  204.         assign ramwr = (ramreq & (~wr_n)) & (~wrdisable);
  205.  
  206.         always @(posedge fclk)
  207.         if( cend && (!cpu_stall) )
  208.         begin
  209.                 ramrd_reg <= ramrd;
  210.                 ramwr_reg <= ramwr;
  211.         end
  212.  
  213.         assign cpureq_357 = ( ramrd & (~ramrd_reg) ) | ( ramwr & (~ramwr_reg) );
  214.        
  215.  
  216.  
  217.  
  218.         assign zd_ena = (~mreq_n) & (~rd_n) & (~romnram);
  219.  
  220.  
  221.         wire       code_cache_select;
  222.         reg [15:1] code_cached_addr;
  223.         reg        code_cached_addr_valid;
  224.         reg [15:0] code_cached_word;
  225.  
  226.         wire       data_cache_select;
  227.         reg [15:1] data_cached_addr;
  228.         reg        data_cached_addr_valid;
  229.         reg [15:0] data_cached_word;
  230.  
  231.         wire cache_hit;
  232.         wire [15:0] selected_cache;
  233.  
  234.         assign code_cache_select = (za[15:1] == code_cached_addr[15:1]);
  235.         assign data_cache_select = (za[15:1] == data_cached_addr[15:1]);
  236.  
  237.         assign cache_hit = (code_cache_select && code_cached_addr_valid) || (data_cache_select && data_cached_addr_valid);
  238.         assign selected_cache = (data_cache_select && data_cached_addr_valid) ? data_cached_word : code_cached_word;
  239.  
  240.         // strobe the beginnings of DRAM cycles
  241.  
  242.         always @(posedge fclk)
  243.         if( zneg )
  244.                 r_mreq_n <= mreq_n | (~rfsh_n);
  245.         //
  246.         assign dram_beg = ( !cache_hit || memwr ) && zneg && r_mreq_n && (!romnram) && (!mreq_n) && rfsh_n;
  247.  
  248.         // access type
  249.         assign opfetch = (~mreq_n) && (~m1_n);
  250.         assign memrd   = (~mreq_n) && (~rd_n);
  251.         assign memwr   = (~mreq_n) &&   rd_n && rfsh_n && (!wrdisable);
  252.  
  253.  
  254.         // wait tables:
  255.         //
  256.         // M1 opcode fetch, dram_beg coincides with:
  257.         // cend:      +3
  258.         // pre_cend:  +4
  259.         // post_cbeg: +5
  260.         // cbeg:      +6
  261.         //
  262.         // memory read, dram_beg coincides with:
  263.         // cend:      +2
  264.         // pre_cend:  +3
  265.         // post_cbeg: +4
  266.         // cbeg:      +5
  267.         //
  268.         // memory write: no wait
  269.         //
  270.         // special case: if dram_beg pulses 1 when cpu_next is 0,
  271.         // unconditional wait has to be performed until cpu_next is 1, and
  272.         // then wait as if dram_beg would coincide with cbeg
  273.  
  274.         assign stall14_ini = dram_beg && ( (!cpu_next) || opfetch || memrd ); // no wait at all in write cycles, if next dram cycle is available
  275.  
  276.  
  277.         // memrd, opfetch - wait till cend & cpu_next,
  278.         // memwr - wait till cpu_next
  279.         assign stall14_cyc = memwr ? (!cpu_next) : stall14_cycrd;
  280.         //
  281.         always @(posedge fclk, negedge rst_n)
  282.         if( !rst_n )
  283.                 stall14_cycrd <= 1'b0;
  284.         else // posedge fclk
  285.         begin
  286.                 if( cpu_next && cend )
  287.                         stall14_cycrd <= 1'b0;
  288.                 else if( dram_beg && ( (!cend) || (!cpu_next) ) && (opfetch || memrd) )
  289.                         stall14_cycrd <= 1'b1;
  290.         end
  291.         //
  292.         always @(posedge fclk, negedge rst_n)
  293.         if( !rst_n )
  294.                 stall14_fin <= 1'b0;
  295.         else // posedge fclk
  296.         begin
  297.                 if( stall14_fin && ( (opfetch&pre_cend) || (memrd&post_cbeg) ) )
  298.                         stall14_fin <= 1'b0;
  299.                 else if( cpu_next && cend && cpu_req && (opfetch || memrd) )
  300.                         stall14_fin <= 1'b1;
  301.         end
  302.  
  303.  
  304.         //
  305.         assign cpu_stall = int_turbo[1] ? (stall14_ini | stall14_cyc | stall14_fin) : (cpureq_357 && (!cpu_next));
  306.  
  307.         // cpu request
  308.         assign cpu_req = int_turbo[1] ? (pending_cpu_req | dram_beg) : cpureq_357;
  309.         //
  310.         assign cpu_rnw = int_turbo[1] ? (dram_beg ? (!memwr) : cpu_rnw_r) : ramrd;
  311.         //
  312.         //
  313.         always @(posedge fclk, negedge rst_n)
  314.         if( !rst_n )
  315.                 pending_cpu_req <= 1'b0;
  316.         else if( cpu_next && cend )
  317.                 pending_cpu_req <= 1'b0;
  318.         else if( dram_beg )
  319.                 pending_cpu_req <= 1'b1;
  320.         //
  321.         always @(posedge fclk)
  322.         if( dram_beg )
  323.                 cpu_rnw_r <= !memwr;
  324.  
  325.  
  326.  
  327.         // address, data in and data out
  328.         //
  329.         assign cpu_wrbsel = za[0];
  330.         assign cpu_addr[20:0] = { page[7:0], za[13:1] };
  331.         assign cpu_wrdata = zd_in;
  332.         //
  333.         always @* if( cpu_strobe ) // WARNING! ACHTUNG! LATCH!!!
  334.                 if (m1_n)
  335.                         data_cached_word <= cpu_rddata;
  336.                 else
  337.                         code_cached_word <= cpu_rddata;
  338.        
  339.         //
  340.         assign zd_out = cpu_wrbsel ? selected_cache[7:0] : selected_cache[15:8];
  341.  
  342.  
  343.  
  344.  
  345.  
  346.         wire io;
  347.         reg  io_r;
  348.         //
  349.         assign io = (~iorq_n);
  350.         //
  351.         always @(posedge fclk)
  352.         if( zpos )
  353.                 io_r <= io;
  354.         //
  355.         always @(posedge fclk, negedge rst_n)
  356.         if( !rst_n )
  357.         begin
  358.                 code_cached_addr_valid <= 1'b0;
  359.                 data_cached_addr_valid <= 1'b0;
  360.         end
  361.         else
  362.         begin
  363.                 if( (zneg && r_mreq_n && (!mreq_n) && rfsh_n && romnram) ||
  364.                     (zneg && r_mreq_n && memwr                         ) ||
  365.                     (io && (!io_r) && zpos                             ) ||
  366.                     (nmi_buf_clr                                       ) )
  367.                         begin
  368.                                 if (memwr)
  369.                                 begin
  370.                                         if (code_cache_select)
  371.                                                 code_cached_addr_valid <= 1'b0;
  372.                                         if (data_cache_select)
  373.                                                 data_cached_addr_valid <= 1'b0;
  374.                                 end
  375.                                 else
  376.                                 begin
  377.                                         data_cached_addr_valid <= 1'b0;
  378.                                         code_cached_addr_valid <= 1'b0;
  379.                                 end
  380.                         end
  381.                 else if( cpu_strobe )
  382.                         begin
  383.                                 if (m1_n)
  384.                                         data_cached_addr_valid <= 1'b1;
  385.                                 else
  386.                                         code_cached_addr_valid <= 1'b1;
  387.                         end
  388.         end
  389.         //
  390.         always @(posedge fclk)
  391.         if( !rst_n )
  392.         begin
  393.                 //code_cached_addr <= 15'd0;
  394.                 //data_cached_addr <= 15'd0;
  395.         end
  396.         else if( cpu_strobe )
  397.         begin
  398.                 if (m1_n)
  399.                         data_cached_addr[15:1] <= za[15:1];
  400.                 else
  401.                         code_cached_addr[15:1] <= za[15:1];
  402.         end
  403.  
  404.  
  405.  
  406.  
  407. endmodule
  408.  
  409.