Subversion Repositories ngs

Rev

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

  1. // part of NeoGS flash programmer project (c) 2014 lvd^NedoPC
  2. //
  3. // rom controller
  4. //
  5. // !!!!!!!!!!!enables addr bus as soon as reset is removed!!!!!!!
  6.  
  7. module rom
  8. (
  9.         input  wire clk,
  10.         input  wire rst_n,
  11.        
  12.         input  wire        wr_addr,
  13.         input  wire        wr_data,
  14.         input  wire        rd_data,
  15.         input  wire [ 7:0] wr_buffer,
  16.         output reg  [ 7:0] rd_buffer,
  17.  
  18.         input  wire        autoinc_ena,
  19.  
  20.         output wire [18:0] rom_a,
  21.         inout  wire [ 7:0] rom_d,
  22.         output reg         rom_cs_n,
  23.         output reg         rom_oe_n,
  24.         output reg         rom_we_n
  25. );
  26.  
  27.         reg  [7:0] wrdata;
  28.         wire [7:0] rddata;
  29.         reg        enadata;
  30.  
  31.         reg [18:0] addr;
  32.         reg [18:0] next_addr;
  33.         reg        enaaddr;
  34.  
  35.         reg [2:0] addr_phase;
  36.  
  37.         reg       rnw;
  38.         reg [6:0] rw_phase;
  39.  
  40.  
  41.         // dbus control
  42.         assign rom_d  = enadata ? wrdata : 8'bZZZZ_ZZZZ;
  43.         assign rddata = rom_d;
  44.  
  45.         // abus control
  46.         assign rom_a = enaaddr ? addr : {19{1'bZ}};
  47.  
  48.  
  49.  
  50.         // enaaddr control
  51.         always @(posedge clk, negedge rst_n)
  52.         if( !rst_n )
  53.                 enaaddr <= 1'b0;
  54.         else
  55.                 enaaddr <= 1'b1;
  56.  
  57.         // address phase (points which one of 3byte address to write into)
  58.         always @(posedge clk, negedge rst_n)
  59.         if( !rst_n )
  60.         begin
  61.                 addr_phase <= 3'b001;
  62.         end
  63.         else
  64.         case( {wr_addr, wr_data, rd_data} )
  65.                 3'b100:        addr_phase <= {addr_phase[1:0], addr_phase[2] };
  66.                 3'b010,3'b001: addr_phase <= 3'b001;
  67.                 default:       addr_phase <= addr_phase;
  68.         endcase
  69.  
  70.         // address control
  71.         always @(posedge clk, negedge rst_n)
  72.         if( !rst_n )
  73.         begin
  74.                 next_addr <= 19'd0;
  75.         end
  76.         else
  77.         case( {wr_addr, wr_data, rd_data} )
  78.                 3'b100: begin
  79.                         next_addr[ 7:0 ] <= addr_phase[0] ? wr_buffer[7:0] : next_addr[ 7:0 ];
  80.                         next_addr[15:8 ] <= addr_phase[1] ? wr_buffer[7:0] : next_addr[15:8 ];
  81.                         next_addr[18:16] <= addr_phase[2] ? wr_buffer[2:0] : next_addr[18:16];
  82.                 end
  83.                 3'b010, 3'b001: if( autoinc_ena ) next_addr <= next_addr + 19'd1;
  84.                 default:        next_addr <= next_addr;
  85.         endcase
  86.  
  87.         // address output register
  88.         always @(posedge clk)
  89.         if( wr_data || rd_data )
  90.                 addr <= next_addr;
  91.  
  92.  
  93.         // read/write sequence
  94.         always @(posedge clk, negedge rst_n)
  95.         if( !rst_n )
  96.         begin
  97.                 rw_phase <= 'd0;
  98.                 rnw      <= 1'b1;
  99.         end
  100.         else if( rd_data || wr_data )
  101.         begin
  102.                 rw_phase <= 'd1;
  103.                 rnw      <= rd_data;
  104.         end
  105.         else
  106.         begin
  107.                 rw_phase <= rw_phase<<1;
  108.         end
  109.  
  110.         // output control
  111.         always @(posedge clk, negedge rst_n)
  112.         if( !rst_n )
  113.         begin
  114.                 enadata <= 1'b0;
  115.         end
  116.         else if( rw_phase[0] )
  117.         begin
  118.                 enadata <= !rnw;
  119.         end
  120.         else if( rw_phase[6] )
  121.         begin
  122.                 enadata <= 1'b0;
  123.         end
  124.         //
  125.         always @(posedge clk, negedge rst_n)
  126.         if( !rst_n )
  127.         begin
  128.                 rom_cs_n <= 1'b1;
  129.                 rom_oe_n <= 1'b1;
  130.                 rom_we_n <= 1'b1;
  131.         end
  132.         else if( rw_phase[1] )
  133.         begin
  134.                 rom_cs_n <= 1'b0;
  135.                 rom_oe_n <= !rnw;
  136.                 rom_we_n <=  rnw;
  137.         end
  138.         else if( rw_phase[6] )
  139.         begin
  140.                 rom_cs_n <= 1'b1;
  141.                 rom_oe_n <= 1'b1;
  142.                 rom_we_n <= 1'b1;
  143.         end
  144.         //
  145.         always @(posedge clk)
  146.         if( wr_data )
  147.                 wrdata <= wr_buffer;
  148.  
  149.  
  150.  
  151.         // input control
  152.         always @(posedge clk)
  153.         if( rw_phase[6] && rnw )
  154.                 rd_buffer <= rddata;
  155.  
  156.  
  157.  
  158. endmodule
  159.  
  160.  
  161.