flashmm.v
3.15 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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// flashmm.v v1 Frank Berndt
// flash memory module;
// :set tabstop=4
module flashmm (
fl_md, fl_db, fl_ce, fl_cle, fl_ale, fl_we, fl_re, fl_wp, fl_ryby
);
output fl_md; // module detect;
inout [7:0] fl_db; // data bus;
input [3:0] fl_ce; // chip enables;
input fl_ale; // address latch enable;
input fl_cle; // command latch enable;
input fl_re; // read eanble;
input fl_we; // write eanble;
input fl_wp; // write protect;
output fl_ryby; // ready/busy;
// flash memory module detect;
// instantiate flash memory module;
// pulled up on chip side, grounded on module side;
// overwrite this to simulate module presence;
reg fl_md; // 0 means present;
initial
fl_md = $test$plusargs("no_module");
// comilation flag;
reg [3:0] fl_comp; // compiled-in flash components;
initial
begin
fl_comp = 4'h0;
`ifdef FLASH0
fl_comp[0] = 1;
`endif // FLASH0
`ifdef FLASH1
fl_comp[1] = 1;
`endif // FLASH1
`ifdef FLASH2
fl_comp[2] = 1;
`endif // FLASH2
`ifdef FLASH3
fl_comp[3] = 1;
`endif // FLASH3
end
// instantiate four NAND flash models;
// use different sizes;
// turn off ce if module detect is 1;
wand fl_ryby;
`ifdef FLASH0
`FLASH0 flash0 (
.io(fl_db),
.cle(fl_cle),
.ale(fl_ale),
.ceb(fl_ce[0] | fl_md),
.reb(fl_re),
.web(fl_we),
.rbb(fl_ryby),
.wpb(fl_wp),
.seb(1'b0)
);
`endif // FLASH0
`ifdef FLASH1
`FLASH1 flash1 (
.io(fl_db),
.cle(fl_cle),
.ale(fl_ale),
.ceb(fl_ce[1] | fl_md),
.reb(fl_re),
.web(fl_we),
.rbb(fl_ryby),
.wpb(fl_wp),
.seb(1'b0)
);
`endif // FLASH1_PRESENT
`ifdef FLASH2
`FLASH2 flash2 (
.io(fl_db),
.cle(fl_cle),
.ale(fl_ale),
.ceb(fl_ce[2] | fl_md),
.reb(fl_re),
.web(fl_we),
.rbb(fl_ryby),
.wpb(fl_wp),
.seb(1'b0)
);
`endif // FLASH2
`ifdef FLASH3
`FLASH3 flash3 (
.io(fl_db),
.cle(fl_cle),
.ale(fl_ale),
.ceb(fl_ce[3] | fl_md),
.reb(fl_re),
.web(fl_we),
.rbb(fl_ryby),
.wpb(fl_wp)
);
`endif // FLASH3
`ifdef NFLASH3
nflash nflash3 (
.dev(2'd3),
.db(fl_db),
.ce(fl_ce[3] | fl_md),
.cle(fl_cle),
.ale(fl_ale),
.we(fl_we),
.re(fl_re),
.wp(fl_wp),
.ryby(fl_ryby)
);
`endif // NFLASH3
// flash module insertion/removal logic;
// timing parameter list, 0 marks end of list;
// bit[14:0] delay in sysclk;
// bit[15] 0=insert, 1=remove module;
// set md_busy to 1 to start events;
// md_busy clears itself when done;
reg [15:0] md_iolist [0:1023]; // parameter list;
reg [7:0] md_ioptr; // ptr to current entry;
reg md_busy; // trigger list processing;
reg [15:0] md_val; // current value;
reg md_valx; // value has Xs in it;
reg md_new; // new md state;
initial
begin
md_busy = 0;
md_iolist[0] = 0;
$readmemh("tests/mdio.dat", md_iolist);
end
always @(posedge md_busy)
begin
md_ioptr = 0;
md_val = md_iolist[md_ioptr];
while(md_busy & (md_val != 0)) begin
md_valx = ^md_val;
if(md_valx === 1'bx)
$display("ERROR: %t: %M: md_iolist[%0d] 0x%h", $time, md_ioptr, md_val);
md_new = md_val[15];
md_val[15] = 0;
repeat(md_val) @(posedge vsim.bb.sysclk);
fl_md = md_new;
md_ioptr = md_ioptr + 1;
md_val = md_iolist[md_ioptr];
end
md_busy = 0;
end
endmodule