Subversion Repositories ngs

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

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