Top secrets sources NedoPC pentevo

Rev

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

`include "../include/tune.v"

module drammem(
        input   [9:0] ma,
        inout [15:0] d,
        input ras_n,
        input ucas_n,
        input lcas_n,
        input we_n
);

        parameter _verbose_ = 1;
        parameter _add_to_addr_ = 0;
        parameter _filter_out_ = 32'h91;
        parameter _init_ = 1;

        reg [15:0] array [0:1048575];
        reg [15:0] dout;

        reg [19:0] addr;

        wire cas_n;

        wire idle;

        reg was_ras;
        reg was_cas;
        reg ready;



        initial
        begin : clear_mem
                integer i;

                if( _init_ )
                begin
                        for(i=0;i<1048576;i=i+1)
                                array[i] = 16'hDEAD;
                end
        end





        always @(negedge ras_n)
                addr[9:0] <= ma[9:0];

        assign cas_n = ucas_n & lcas_n;
        always @(negedge cas_n)
        begin
                addr[19:10] <= ma[9:0];
        end

        always @(posedge cas_n, negedge cas_n)
                ready <= ~cas_n; // to introduce delta-cycle in ready to allow capturing of CAS address before proceeding data


        assign idle = ras_n & cas_n;

        always @(negedge ras_n, posedge idle)
        begin
                if( idle )
                        was_ras <= 1'b0;
                else // negedge ras_n
                        was_ras <= 1'b1;
        end

        always @(negedge cas_n, posedge idle)
        begin
                if( idle )
                        was_cas <= 1'b0;
                else
                        if( was_ras )
                                was_cas <= 1'b1;
        end





        assign d = dout;

        always @*
        begin
                if( ready && was_ras && was_cas && we_n && (~idle) ) // idle here is to prevent races at the end of all previous signals, which cause redundant read at the end of write
                begin
                        dout = array[addr];
`ifdef DRAMMEM_VERBOSE
                        if( _verbose_ == 1 )
                        begin
                                if( addr != _filter_out_ )
                                        $display("DRAM read at %t: ($%h)=>$%h",$time,addr*2+_add_to_addr_,dout);
                        end
`endif
                end
                else
                begin
                        dout = 16'hZZZZ;
                end
        end


        always @*
                if( ready && was_ras && was_cas && (~we_n) && (~idle) )
                begin
                        if( ~ucas_n )
                                array[addr][15:8] = d[15:8];

                        if( ~lcas_n )
                                array[addr][7:0] = d[7:0];

`ifdef DRAMMEM_VERBOSE
                        if( _verbose_ == 1 )
                        begin
                                if( addr != _filter_out_ )
                                        $display("DRAM written at %t: ($%h)<=$%h.$%h",$time,addr*2+_add_to_addr_,ucas_n?8'hXX:d[15:8],lcas_n?8'hXX:d[7:0]);
                        end
`endif
                end




endmodule