Top secrets sources NedoPC ngs

Rev

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

// part of NeoGS flash programmer project (c) 2014 lvd^NedoPC
//
// rom controller
//
// !!!!!!!!!!!enables addr bus as soon as reset is removed!!!!!!!

module rom
(
        input  wire clk,
        input  wire rst_n,
       
        input  wire        wr_addr,
        input  wire        wr_data,
        input  wire        rd_data,
        input  wire [ 7:0] wr_buffer,
        output reg  [ 7:0] rd_buffer,

        input  wire        autoinc_ena,

        output wire [18:0] rom_a,
        inout  wire [ 7:0] rom_d,
        output reg         rom_cs_n,
        output reg         rom_oe_n,
        output reg         rom_we_n
);

        reg  [7:0] wrdata;
        wire [7:0] rddata;
        reg        enadata;

        reg [18:0] addr;
        reg [18:0] next_addr;
        reg        enaaddr;

        reg [2:0] addr_phase;

        reg       rnw;
        reg [6:0] rw_phase;


        // dbus control
        assign rom_d  = enadata ? wrdata : 8'bZZZZ_ZZZZ;
        assign rddata = rom_d;

        // abus control
        assign rom_a = enaaddr ? addr : {19{1'bZ}};



        // enaaddr control
        always @(posedge clk, negedge rst_n)
        if( !rst_n )
                enaaddr <= 1'b0;
        else
                enaaddr <= 1'b1;

        // address phase (points which one of 3byte address to write into)
        always @(posedge clk, negedge rst_n)
        if( !rst_n )
        begin
                addr_phase <= 3'b001;
        end
        else
        case( {wr_addr, wr_data, rd_data} )
                3'b100:        addr_phase <= {addr_phase[1:0], addr_phase[2] };
                3'b010,3'b001: addr_phase <= 3'b001;
                default:       addr_phase <= addr_phase;
        endcase

        // address control
        always @(posedge clk, negedge rst_n)
        if( !rst_n )
        begin
                next_addr <= 19'd0;
        end
        else
        case( {wr_addr, wr_data, rd_data} )
                3'b100: begin
                        next_addr[ 7:0 ] <= addr_phase[0] ? wr_buffer[7:0] : next_addr[ 7:0 ];
                        next_addr[15:8 ] <= addr_phase[1] ? wr_buffer[7:0] : next_addr[15:8 ];
                        next_addr[18:16] <= addr_phase[2] ? wr_buffer[2:0] : next_addr[18:16];
                end
                3'b010, 3'b001: if( autoinc_ena ) next_addr <= next_addr + 19'd1;
                default:        next_addr <= next_addr;
        endcase

        // address output register
        always @(posedge clk)
        if( wr_data || rd_data )
                addr <= next_addr;


        // read/write sequence
        always @(posedge clk, negedge rst_n)
        if( !rst_n )
        begin
                rw_phase <= 'd0;
                rnw      <= 1'b1;
        end
        else if( rd_data || wr_data )
        begin
                rw_phase <= 'd1;
                rnw      <= rd_data;
        end
        else
        begin
                rw_phase <= rw_phase<<1;
        end

        // output control
        always @(posedge clk, negedge rst_n)
        if( !rst_n )
        begin
                enadata <= 1'b0;
        end
        else if( rw_phase[0] )
        begin
                enadata <= !rnw;
        end
        else if( rw_phase[6] )
        begin
                enadata <= 1'b0;
        end
        //
        always @(posedge clk, negedge rst_n)
        if( !rst_n )
        begin
                rom_cs_n <= 1'b1;
                rom_oe_n <= 1'b1;
                rom_we_n <= 1'b1;
        end
        else if( rw_phase[1] )
        begin
                rom_cs_n <= 1'b0;
                rom_oe_n <= !rnw;
                rom_we_n <=  rnw;
        end
        else if( rw_phase[6] )
        begin
                rom_cs_n <= 1'b1;
                rom_oe_n <= 1'b1;
                rom_we_n <= 1'b1;
        end
        //
        always @(posedge clk)
        if( wr_data )
                wrdata <= wr_buffer;



        // input control
        always @(posedge clk)
        if( rw_phase[6] && rnw )
                rd_buffer <= rddata;



endmodule