NI_MROM_64M.v
2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
`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