NI_MROM_64M.v 2.74 KB
`timescale 1ns/1ns

module NI_MROM_64M (
        AD, ALEH, ALEL, CEB , RDB
        );

inout  [15:0] AD;
input  ALEH, ALEL, CEB, RDB;

parameter CMPD = 4'b0000;
parameter tRD = 150 , tOH = 0;
parameter FILE_NAME = "rom_";
parameter FILE_EXT = ".data";

reg         in_CEB;
reg  [15:0] in_AD;
reg         CE_reg, CS_reg;
reg   [6:0] H_ADR;
reg  [15:1] L_ADR;
reg  [15:0] DO ;
wire        rdb;
wire [21:0] adr;
reg  [15:0] rom_data [0:22'h3fffff];

   initial begin : load_memory
     reg [7:0] file_number;
     reg [19*8-1:0] file_name;

     if ($test$plusargs("load_rom")) begin
       if (CMPD > 9) file_number = "a" + CMPD - 10;
       else          file_number = "0" + CMPD;

       file_name = {FILE_NAME, file_number, FILE_EXT};

       $display("loading ROM %h from %s...", CMPD[3:0], file_name);
       $readmemh(file_name, rom_data);
       end
     end


    assign AD = DO;

    always @( ALEL or CEB or AD )
      begin
        if ( ALEL == 1'b1 )
            { in_CEB, in_AD } <= { CEB, AD };
        else
            { in_CEB, in_AD } <= { 1'b1, 16'hffff };
    end

    always @( negedge ALEH ) begin
        H_ADR  <= in_AD[6:0];
        CE_reg <= in_CEB;
        casex( { in_AD[12:11], in_AD[8:7] } )
            CMPD:    CS_reg <= 1'b0;
            default: CS_reg <= 1'b1;
        endcase
    end

    always @( negedge ALEL ) begin
        if( ALEH == 1'b0 ) L_ADR <= in_AD[15:1];
    end

    always @( posedge rdb ) begin
        L_ADR[8:1] <= L_ADR[8:1] + 1'b1;
    end

    assign adr = { H_ADR, L_ADR };
//    assign #tRD rdb = RDB | CE_reg | CS_reg | ALEH | ALEL;
    assign rdb = RDB | CE_reg | CS_reg | ALEH | ALEL;

    always @( rdb ) begin
        if( rdb == 1'b0 )
            DO <= #tRD rom_data[ adr ];
        else
            DO <= #tOH 16'hzzzz;
    end

    specify
        specparam tALES = 70;   /* ALEL setup to ALEH negedge */
        specparam tALED = 70;   /* ALEL hold to ALEH negedge */
        specparam tAS   = 40;   /* AD15-0 setup to ALEH negedge */
        specparam tAH   = 0;    /* AD15-0 hold to ALEH negedge */
        specparam tCES  = 40;   /* CEB setup to ALEH negedge */
        specparam tCEH  = 0;    /* CEB hold to ALEH negedge */
        specparam tL    = 2000; /* read latency */
        specparam tCYC  = 400;  /* RDB period */
        specparam tR    = 20;   /* RDB width */
        specparam tREL  = 0;    /* RDB release */
        $setuphold( negedge ALEH, ALEL, tALES, tALED );
        $setuphold( negedge ALEH, AD, tAS, tAH );
        $setuphold( negedge ALEL, AD, tAS, tAH );
        $setuphold( negedge ALEH, CEB, tCES, tCEH );
        $recovery( negedge ALEL, negedge RDB, tL );
        $recovery( posedge RDB, posedge ALEH, tREL );
        $width( posedge RDB, tR );
        $period( negedge RDB, tCYC );
    endspecify

endmodule