Subversion Repositories ngs

Rev

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

  1. // Part of NeoGS project
  2. //
  3. // FPGA early and on-the-fly configuration, Z80 clock switch,
  4. // 3.3v RAM buffer
  5. //
  6. // (c) 2008-2010 NedoPC
  7.  
  8. module GS_cpld(
  9.         output reg         config_n,  // ACEX1K config pins
  10.         input  wire        status_n,  //
  11.         input  wire        conf_done, //
  12.         output wire        cs,        //
  13.         input  wire        init_done, //
  14.  
  15.  
  16.         input  wire        clk24in, // 24mhz in
  17.         input  wire        clk20in, // 20mhz in
  18.         input  wire        clksel0, // clock select 0 (1=divide by 2, 0=no divide)
  19.         input  wire        clksel1, // clock select 1 (1=clk20in, 0=clk24in)
  20.         output wire        clkout,  // clock out
  21.  
  22.         input  wire        clkin, // input of clkout signal, buffered, same as for Z80
  23.  
  24.  
  25.         input  wire        coldres_n, // resets
  26.         output reg         warmres_n,
  27.  
  28.  
  29.         input  wire        iorq_n, // Z80 control signals
  30.         input  wire        mreq_n,
  31.         input  wire        rd_n,
  32.         input  wire        wr_n,
  33.  
  34.         inout  wire [ 7:0] d, // Z80 data bus
  35.  
  36.         input  wire        a6,  // some Z80 addresses
  37.         input  wire        a7,
  38.         input  wire        a10,
  39.         input  wire        a11,
  40.         input  wire        a12,
  41.         input  wire        a13,
  42.         input  wire        a14,
  43.         input  wire        a15,
  44.  
  45.  
  46.         output wire        mema14,
  47.         output wire        mema15,
  48.         output wire        mema19,
  49.  
  50.         inout  wire        romcs_n,
  51.         inout  wire        memoe_n,
  52.         inout  wire        memwe_n,
  53.  
  54.         input  wire        in_ramcs0_n,
  55.         input  wire        in_ramcs1_n,
  56.         input  wire        in_ramcs2_n,
  57.         input  wire        in_ramcs3_n,
  58.  
  59.         output wire        out_ramcs0_n,
  60.         output wire        out_ramcs1_n,
  61.  
  62.  
  63.         output wire        ra6,  // some buffered memory addresses
  64.         output wire        ra7,
  65.         output wire        ra10,
  66.         output wire        ra11,
  67.         output wire        ra12,
  68.         output wire        ra13,
  69.  
  70.         inout  wire [ 7:0] rd // memory data bus
  71. );
  72.  
  73.  
  74.  
  75.  
  76.         reg int_mema14,int_mema15;
  77.         reg int_romcs_n,int_ramcs_n;
  78.         wire int_memoe_n,int_memwe_n;
  79.         wire int_cs;
  80.  
  81.         wire ext_romcs_n,
  82.              ext_memoe_n,
  83.              ext_memwe_n;
  84.  
  85.  
  86.         reg [1:0] memcfg; // memcfg[1]: 1 ram, 0 roms
  87.                           // memcfg[0]: 0 page0, 1 page1 -> in 8000-ffff region
  88.  
  89.         reg disbl; // =1 - cpld disabled, =0 - enabled
  90.  
  91.         reg was_cold_reset_n; // 1 - no cold reset, 0 - was cold reset
  92.  
  93.  
  94.         reg  [1:0] dbout;
  95.         wire [1:0] dbin;
  96.  
  97.         wire memcfg_write_n;
  98.         wire rescfg_write_n;
  99.  
  100.         wire coldrstf_read_n;
  101.         wire fpgastat_read_n;
  102.  
  103.  
  104.  
  105.  
  106.         assign dbin[1] = d[7];
  107.         assign dbin[0] = d[0];
  108.  
  109.  
  110.  
  111.         reg [3:0] rstcount; // counter for warm reset period
  112.  
  113.         reg [2:0] disbl_sync;
  114.  
  115.         // PORTS:
  116.         // {a7,a6}
  117.         // 00 - fpga ports
  118.         // 01,WR - write memcfg: d7=RAM(1)/ROM(0), d0=32k page(0/1)
  119.         // 01,RD - read cold_reset_n flag: d7=(0:was cold reset,1:no cold reset)
  120.         // 10,WR - set cold_reset_n flag & write FPGA nCONFIG: d7=1: set cold_reset_n flag, d0: nCONFIG
  121.         // 10,RD - read FPGA status: d7=nSTATUS, d0=CONF_DONE
  122.         // 11,WR - write to FPGA
  123.         // 11,RD - read from FPGA
  124.  
  125.  
  126.         // clock selector
  127.         clocker clk( .clk1(clk24in),
  128.                      .clk2(clk20in),
  129.                      .clksel(clksel1),
  130.                      .divsel(clksel0),
  131.                      .clkout(clkout)
  132.                    );
  133.  
  134.  
  135.         // disable control
  136.  
  137.         always @(negedge config_n,posedge init_done)
  138.         begin
  139.                 if( !config_n ) // asynchronous reset
  140.                         disbl <= 0;
  141.                 else // posedge of init_done, synchronous set
  142.                         disbl <= 1;
  143.         end
  144.  
  145.  
  146.  
  147.         // memory control pins when running without configured FPGA
  148.         assign mema14  = disbl ? 1'bZ : int_mema14;
  149.         assign mema15  = disbl ? 1'bZ : int_mema15;
  150.         assign romcs_n = disbl ? 1'bZ : int_romcs_n;
  151.         assign memoe_n = disbl ? 1'bZ : int_memoe_n;
  152.         assign memwe_n = disbl ? 1'bZ : int_memwe_n;
  153.         assign cs      = disbl ? 1'bZ : int_cs;
  154.  
  155.         assign ext_romcs_n = romcs_n;
  156.         assign ext_memoe_n = memoe_n;
  157.         assign ext_memwe_n = memwe_n;
  158.  
  159.  
  160.         // controlling memory paging
  161.         always @*
  162.         begin
  163.                 casex( {a15,a14,memcfg[1]} )
  164.                 3'b00x:
  165.                         {int_mema15,int_mema14,int_romcs_n,int_ramcs_n} <= 4'b0001;
  166.                 3'b01x:
  167.                         {int_mema15,int_mema14,int_romcs_n,int_ramcs_n} <= 4'b0010;
  168.                 3'b1x0:
  169.                         {int_mema15,int_mema14,int_romcs_n,int_ramcs_n} <= {memcfg[0],a14,2'b01};
  170.                 3'b1x1:
  171.                         {int_mema15,int_mema14,int_romcs_n,int_ramcs_n} <= {memcfg[0],a14,2'b10};
  172.                 endcase
  173.         end
  174.  
  175.         // controlling memory /OE, /WE
  176.         assign int_memoe_n = mreq_n | rd_n;
  177.         assign int_memwe_n = mreq_n | wr_n;
  178.  
  179.  
  180.         // writing paging register [1:0] memcfg
  181.         assign memcfg_write_n = iorq_n | wr_n | a7 | ~a6; // {a7,a6}==01
  182.  
  183.         always @(negedge coldres_n, posedge memcfg_write_n)
  184.         begin
  185.                 if( !coldres_n ) // reset on coldres_n
  186.                         memcfg <= 2'b00;
  187.                 else // write on memcfg_write_n
  188.                         memcfg <= dbin;
  189.         end
  190.  
  191.  
  192.         // writing nCONFIG and cold reset "register"
  193.         assign rescfg_write_n = iorq_n | wr_n | ~a7 | a6; // {a7,a6}==10
  194.  
  195.         always @(posedge rescfg_write_n, negedge coldres_n)
  196.         begin
  197.                 if( !coldres_n ) // async reset
  198.                 begin
  199.                         was_cold_reset_n <= 0; // there was!
  200.                         config_n <= 0; // start FPGA config
  201.                 end
  202.                 else // sync set/load
  203.                 begin
  204.                         config_n <= dbin[0];
  205.                         was_cold_reset_n <= dbin[1] | was_cold_reset_n;
  206.                 end
  207.         end
  208.  
  209.  
  210.         // controlling positive CS pin to FPGA
  211.         assign int_cs = a7 & a6; // {a7,a6}==11
  212.  
  213.  
  214.  
  215.         // reading control
  216.         assign coldrstf_read_n = iorq_n | rd_n | a7 | ~a6; // {a7,a6}=01
  217.         assign fpgastat_read_n = iorq_n | rd_n | ~a7 | a6; // {a7,a6}=10
  218.  
  219.  
  220.  
  221.         always @*
  222.         begin
  223.                 case( {coldrstf_read_n,fpgastat_read_n} )
  224.                         2'b01:
  225.                                 dbout = { was_cold_reset_n, 1'bX };
  226.                         2'b10:
  227.                                 dbout = { status_n, conf_done };
  228.                         default:
  229.                                 dbout = 2'bXX;
  230.                 endcase
  231.         end
  232.  
  233.  
  234.  
  235.         // warm resetter control
  236.  
  237.         always @(posedge clkin)
  238.         begin
  239.                 disbl_sync[2:0]={disbl_sync[1:0],disbl};
  240.         end
  241.  
  242.         always @(negedge coldres_n,posedge clkin)
  243.         begin
  244.                 if( coldres_n==0 ) // async reset
  245.                 begin
  246.                         rstcount <= (-1);
  247.                         warmres_n <= 0;
  248.                 end
  249.                 else // posedge clkin
  250.                 begin
  251.                         if( disbl_sync[2]==0 && disbl_sync[1]==1 ) // positive pulse
  252.                         begin
  253.                                 warmres_n <= 0;
  254.                                 rstcount <= (-1);
  255.                         end
  256.                         else // no disbl_sync positive pulse
  257.                         begin
  258.                                 rstcount <= rstcount - 1;
  259.                                 if( |rstcount == 0 )
  260.                                         warmres_n <= 1'bZ;
  261.                         end
  262.                 end
  263.  
  264.         end
  265.  
  266.  
  267.  
  268.         // Z80 data bus control
  269.  
  270.         assign d = ( (!coldrstf_read_n)||(!fpgastat_read_n) )   ?
  271.                    { dbout[1], 6'bXXXXXX, dbout[0] }            :
  272.                    ( (ext_romcs_n&&(!ext_memoe_n)) ? rd : 8'bZZZZZZZZ ) ;
  273.  
  274.         // memory data bus control
  275.  
  276.         assign rd = (ext_romcs_n&&(!ext_memwe_n)) ? d : 8'bZZZZZZZZ;
  277.  
  278.         // memory addresses buffering
  279.  
  280.         assign ra6  = a6;
  281.         assign ra7  = a7;
  282.         assign ra10 = a10;
  283.         assign ra11 = a11;
  284.         assign ra12 = a12;
  285.         assign ra13 = a13;
  286.  
  287.  
  288.         // memory CS'ing
  289.  
  290.         assign out_ramcs0_n = disbl ? ( in_ramcs0_n & in_ramcs1_n ) : int_ramcs_n;
  291.         assign out_ramcs1_n = disbl ? ( in_ramcs2_n & in_ramcs3_n ) : 1'b1;
  292.  
  293.         assign mema19 = disbl ? ( in_ramcs0_n & in_ramcs2_n ) : 1'b0;
  294.  
  295.  
  296.  
  297. endmodule
  298.  
  299.