blob: 5573f7ed3469ba0b5b306a2de746faf224b06bed [file] [log] [blame]
Timothy Chenff4a7702020-10-27 15:08:53 -07001// Copyright lowRISC contributors.
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4//
5// Flash Controller module.
6//
7
8package flash_ctrl_pkg;
9
10 // design parameters that can be altered through topgen
11 parameter int NumBanks = flash_ctrl_reg_pkg::RegNumBanks;
12 parameter int PagesPerBank = flash_ctrl_reg_pkg::RegPagesPerBank;
Timothy Chen9b113e52020-11-06 18:48:05 -080013 parameter int BusPgmResBytes = flash_ctrl_reg_pkg::RegBusPgmResBytes;
Timothy Chenff4a7702020-10-27 15:08:53 -070014
15 // fixed parameters of flash derived from topgen parameters
16 parameter int DataWidth = ${cfg['data_width']};
17 parameter int MetaDataWidth = ${cfg['metadata_width']};
18 parameter int InfoTypes = ${cfg['info_types']}; // How many types of info per bank
19
20// The following hard-wired values are there to work-around verilator.
21// For some reason if the values are assigned through parameters verilator thinks
22// they are not constant
23 parameter int InfoTypeSize [InfoTypes] = '{
24 % for type in range(cfg['info_types']):
25 ${cfg['infos_per_bank'][type]}${"," if not loop.last else ""}
26 % endfor
27 };
28 parameter int InfosPerBank = max_info_pages('{
29 % for type in range(cfg['info_types']):
30 ${cfg['infos_per_bank'][type]}${"," if not loop.last else ""}
31 % endfor
32 });
33 parameter int WordsPerPage = ${cfg['words_per_page']}; // Number of flash words per page
34 parameter int BusWidth = top_pkg::TL_DW;
35 parameter int MpRegions = 8; // flash controller protection regions
36 parameter int FifoDepth = 16; // rd / prog fifos
37 parameter int InfoTypesWidth = prim_util_pkg::vbits(InfoTypes);
38
39 // flash phy parameters
40 parameter int DataByteWidth = prim_util_pkg::vbits(DataWidth / 8);
41 parameter int BankW = prim_util_pkg::vbits(NumBanks);
42 parameter int InfoPageW = prim_util_pkg::vbits(InfosPerBank);
43 parameter int PageW = prim_util_pkg::vbits(PagesPerBank);
44 parameter int WordW = prim_util_pkg::vbits(WordsPerPage);
45 parameter int AddrW = BankW + PageW + WordW; // all flash range
46 parameter int BankAddrW = PageW + WordW; // 1 bank of flash range
47 parameter int AllPagesW = BankW + PageW;
48
49 // flash ctrl / bus parameters
50 // flash / bus width may be different from actual flash word width
Timothy Chen9b113e52020-11-06 18:48:05 -080051 parameter int BusBytes = BusWidth / 8;
52 parameter int BusByteWidth = prim_util_pkg::vbits(BusBytes);
Timothy Chenff4a7702020-10-27 15:08:53 -070053 parameter int WidthMultiple = DataWidth / BusWidth;
Timothy Chen9b113e52020-11-06 18:48:05 -080054 // Number of bus words that can be programmed at once
55 parameter int BusPgmRes = BusPgmResBytes / BusBytes;
56 parameter int BusPgmResWidth = prim_util_pkg::vbits(BusPgmRes);
Timothy Chenff4a7702020-10-27 15:08:53 -070057 parameter int BusWordsPerPage = WordsPerPage * WidthMultiple;
58 parameter int BusWordW = prim_util_pkg::vbits(BusWordsPerPage);
59 parameter int BusAddrW = BankW + PageW + BusWordW;
60 parameter int BusBankAddrW = PageW + BusWordW;
61 parameter int PhyAddrStart = BusWordW - WordW;
62
63 // fifo parameters
64 parameter int FifoDepthW = prim_util_pkg::vbits(FifoDepth+1);
65
66 // The end address in bus words for each kind of partition in each bank
67 parameter logic [PageW-1:0] DataPartitionEndAddr = PagesPerBank - 1;
Timothy Chene97e0b82020-12-11 17:18:43 -080068 //parameter logic [PageW-1:0] InfoPartitionEndAddr [InfoTypes] = '{
69 % for type in range((cfg['info_types'])):
70 // ${cfg['infos_per_bank'][type]-1}${"," if not loop.last else ""}
71 % endfor
72 //};
Timothy Chenff4a7702020-10-27 15:08:53 -070073 parameter logic [PageW-1:0] InfoPartitionEndAddr [InfoTypes] = '{
Timothy Chene97e0b82020-12-11 17:18:43 -080074 % for type in range((cfg['info_types'])):
75 InfoTypeSize[${type}] - 1${"," if not loop.last else ""}
76 % endfor
Timothy Chenff4a7702020-10-27 15:08:53 -070077 };
78
79 ////////////////////////////
80 // All memory protection, seed related parameters
81 // Those related for seed pages should be template candidates
82 ////////////////////////////
83
84 // parameters for connected components
85 parameter int SeedWidth = 256;
Timothy Chenf52a4612020-12-04 20:37:49 -080086 parameter int KeyWidth = 128;
Timothy Chenaeffadc2020-12-11 15:03:07 -080087 parameter int EdnWidth = edn_pkg::ENDPOINT_BUS_WIDTH;
Timothy Chenf52a4612020-12-04 20:37:49 -080088 typedef logic [KeyWidth-1:0] flash_key_t;
Timothy Chenff4a7702020-10-27 15:08:53 -070089
Timothy Chenaeffadc2020-12-11 15:03:07 -080090 // Default Lfsr configurations
91 // These LFSR parameters have been generated with
Michael Schaffner1fff9852021-01-08 14:06:35 -080092 // $ util/design/gen-lfsr-seed.py --width 32 --seed 1274809145 --prefix ""
Timothy Chenaeffadc2020-12-11 15:03:07 -080093 parameter int LfsrWidth = 32;
94 typedef logic [LfsrWidth-1:0] lfsr_seed_t;
95 typedef logic [LfsrWidth-1:0][$clog2(LfsrWidth)-1:0] lfsr_perm_t;
96 parameter lfsr_seed_t RndCnstLfsrSeedDefault = 32'ha8cee782;
97 parameter lfsr_perm_t RndCnstLfsrPermDefault = {
98 160'hd60bc7d86445da9347e0ccdd05b281df95238bb5
99 };
100
101 // These LFSR parameters have been generated with
Michael Schaffner1fff9852021-01-08 14:06:35 -0800102 // $ util/design/gen-lfsr-seed.py --width 64 --seed 691876113 --prefix ""
Timothy Chenaeffadc2020-12-11 15:03:07 -0800103
104
Timothy Chenff4a7702020-10-27 15:08:53 -0700105 // lcmgr phase enum
106 typedef enum logic [1:0] {
107 PhaseSeed,
108 PhaseRma,
109 PhaseNone,
110 PhaseInvalid
111 } flash_lcmgr_phase_e;
112
113 // alias for super long reg_pkg typedef
114 typedef flash_ctrl_reg_pkg::flash_ctrl_reg2hw_bank0_info0_page_cfg_mreg_t info_page_cfg_t;
115 typedef flash_ctrl_reg_pkg::flash_ctrl_reg2hw_mp_region_cfg_mreg_t mp_region_cfg_t;
116
117 // memory protection specific structs
118 typedef struct packed {
119 logic [InfoTypesWidth-1:0] sel;
120 logic [AllPagesW-1:0] addr;
121 } page_addr_t;
122
123 typedef struct packed {
124 page_addr_t page;
125 flash_lcmgr_phase_e phase;
126 info_page_cfg_t cfg;
127 } info_page_attr_t;
128
129 typedef struct packed {
130 flash_lcmgr_phase_e phase;
131 mp_region_cfg_t cfg;
132 } data_region_attr_t;
133
134 // flash life cycle / key manager management constants
135 // One page for creator seeds
136 // One page for owner seeds
Timothy Chen8ea1b412020-11-18 18:32:08 -0800137 // One page for isolated flash page
Timothy Chenff4a7702020-10-27 15:08:53 -0700138 parameter int NumSeeds = 2;
139 parameter int SeedBank = 0;
140 parameter int SeedInfoSel = 0;
141 parameter int CreatorSeedIdx = 0;
142 parameter int OwnerSeedIdx = 1;
143 parameter int CreatorInfoPage = 1;
144 parameter int OwnerInfoPage = 2;
Timothy Chen8ea1b412020-11-18 18:32:08 -0800145 parameter int IsolatedInfoPage = 3;
Timothy Chenff4a7702020-10-27 15:08:53 -0700146
Timothy Chen8ea1b412020-11-18 18:32:08 -0800147 // which page of which info type of which bank for seed selection
Timothy Chenff4a7702020-10-27 15:08:53 -0700148 parameter page_addr_t SeedInfoPageSel [NumSeeds] = '{
149 '{
150 sel: SeedInfoSel,
151 addr: {SeedBank, CreatorInfoPage}
152 },
153
154 '{
155 sel: SeedInfoSel,
156 addr: {SeedBank, OwnerInfoPage}
157 }
158 };
159
Timothy Chen8ea1b412020-11-18 18:32:08 -0800160 // which page of which info type of which bank for isolated partition
161 parameter page_addr_t IsolatedPageSel = '{
162 sel: SeedInfoSel,
163 addr: {SeedBank, IsolatedInfoPage}
164 };
165
Timothy Chenff4a7702020-10-27 15:08:53 -0700166 // hardware interface memory protection rules
167 parameter int HwInfoRules = 3;
168 parameter int HwDataRules = 1;
169
170 parameter info_page_cfg_t CfgAllowRead = '{
171 en: 1'b1,
172 rd_en: 1'b1,
173 prog_en: 1'b0,
174 erase_en: 1'b0,
Timothy Chena2db9332020-11-13 18:47:54 -0800175 scramble_en: 1'b0,
Timothy Chend5323562020-12-02 16:10:44 -0800176 ecc_en: 1'b0, // TBD, update to 1 once tb supports ECC
177 he_en: 1'b1
Timothy Chenff4a7702020-10-27 15:08:53 -0700178 };
179
Timothy Chend39402a2020-12-15 20:34:09 -0800180 parameter info_page_cfg_t CfgAllowReadProgErase = '{
Timothy Chenff4a7702020-10-27 15:08:53 -0700181 en: 1'b1,
182 rd_en: 1'b1,
Timothy Chend39402a2020-12-15 20:34:09 -0800183 prog_en: 1'b1,
Timothy Chenff4a7702020-10-27 15:08:53 -0700184 erase_en: 1'b1,
Timothy Chend39402a2020-12-15 20:34:09 -0800185 scramble_en: 1'b1,
186 ecc_en: 1'b1,
Timothy Chend5323562020-12-02 16:10:44 -0800187 he_en: 1'b1 // HW assumes high endurance
Timothy Chenff4a7702020-10-27 15:08:53 -0700188 };
189
190 parameter info_page_attr_t HwInfoPageAttr[HwInfoRules] = '{
191 '{
192 page: SeedInfoPageSel[CreatorSeedIdx],
193 phase: PhaseSeed,
194 cfg: CfgAllowRead
195 },
196
197 '{
198 page: SeedInfoPageSel[OwnerSeedIdx],
199 phase: PhaseSeed,
200 cfg: CfgAllowRead
201 },
202
203 '{
204 page: SeedInfoPageSel[OwnerSeedIdx],
205 phase: PhaseRma,
Timothy Chend39402a2020-12-15 20:34:09 -0800206 cfg: CfgAllowReadProgErase
Timothy Chenff4a7702020-10-27 15:08:53 -0700207 }
208 };
209
210 parameter data_region_attr_t HwDataAttr[HwDataRules] = '{
211 '{
212 phase: PhaseRma,
213 cfg: '{
214 en: 1'b1,
215 rd_en: 1'b1,
Timothy Chend39402a2020-12-15 20:34:09 -0800216 prog_en: 1'b1,
Timothy Chenff4a7702020-10-27 15:08:53 -0700217 erase_en: 1'b1,
Timothy Chend39402a2020-12-15 20:34:09 -0800218 scramble_en: 1'b1,
219 ecc_en: 1'b1,
Timothy Chend5323562020-12-02 16:10:44 -0800220 he_en: 1'b1, // HW assumes high endurance
Timothy Chenff4a7702020-10-27 15:08:53 -0700221 base: '0,
222 size: '{default:'1}
223 }
224 }
225 };
226
227
228 ////////////////////////////
Timothy Chenf52a4612020-12-04 20:37:49 -0800229 // Design time constants
230 ////////////////////////////
231 parameter flash_key_t RndCnstAddrKeyDefault =
232 128'h5d707f8a2d01d400928fa691c6a6e0a4;
233 parameter flash_key_t RndCnstDataKeyDefault =
234 128'h39953618f2ca6f674af39f64975ea1f5;
235
236 ////////////////////////////
Timothy Chenff4a7702020-10-27 15:08:53 -0700237 // Flash operation related enums
238 ////////////////////////////
239
240 // Flash Operations Supported
241 typedef enum logic [1:0] {
242 FlashOpRead = 2'h0,
243 FlashOpProgram = 2'h1,
244 FlashOpErase = 2'h2,
245 FlashOpInvalid = 2'h3
246 } flash_op_e;
247
248 // Flash Program Operations Supported
249 typedef enum logic {
250 FlashProgNormal = 0,
251 FlashProgRepair = 1
252 } flash_prog_e;
253 parameter int ProgTypes = 2;
254
255 // Flash Erase Operations Supported
256 typedef enum logic {
257 FlashErasePage = 0,
258 FlashEraseBank = 1
259 } flash_erase_e;
260
261 // Flash function select
262 typedef enum logic [1:0] {
263 NoneSel,
264 SwSel,
265 HwSel
266 } flash_sel_e;
267
268 // Flash tlul to fifo direction
269 typedef enum logic {
270 WriteDir = 1'b0,
271 ReadDir = 1'b1
272 } flash_flfo_dir_e;
273
274 // Flash partition type
275 typedef enum logic {
276 FlashPartData = 1'b0,
277 FlashPartInfo = 1'b1
278 } flash_part_e;
279
280 // Flash controller to memory
281 typedef struct packed {
282 logic req;
283 logic scramble_en;
Timothy Chena2db9332020-11-13 18:47:54 -0800284 logic ecc_en;
Timothy Chend5323562020-12-02 16:10:44 -0800285 logic he_en;
Timothy Chenff4a7702020-10-27 15:08:53 -0700286 logic rd;
287 logic prog;
288 logic pg_erase;
289 logic bk_erase;
Timothy Chen7d051eb2020-12-11 14:06:43 -0800290 logic erase_suspend;
Timothy Chenff4a7702020-10-27 15:08:53 -0700291 flash_part_e part;
Timothy Chena0a550a2020-12-03 13:11:03 -0800292 logic [InfoTypesWidth-1:0] info_sel;
Timothy Chenff4a7702020-10-27 15:08:53 -0700293 logic [BusAddrW-1:0] addr;
294 logic [BusWidth-1:0] prog_data;
295 logic prog_last;
296 flash_prog_e prog_type;
297 mp_region_cfg_t [MpRegions:0] region_cfgs;
Timothy Chenf52a4612020-12-04 20:37:49 -0800298 logic [KeyWidth-1:0] addr_key;
299 logic [KeyWidth-1:0] data_key;
Timothy Chen6b241b32020-11-13 15:15:45 -0800300 logic rd_buf_en;
Timothy Chen6e495182020-12-28 16:16:35 -0800301 tlul_pkg::tl_h2d_t tl_flash_c2p;
Timothy Chen16741102021-01-15 17:32:13 -0800302 logic alert_trig;
303 logic alert_ack;
Timothy Chenff4a7702020-10-27 15:08:53 -0700304 } flash_req_t;
305
306 // default value of flash_req_t (for dangling ports)
307 parameter flash_req_t FLASH_REQ_DEFAULT = '{
Timothy Chen7d051eb2020-12-11 14:06:43 -0800308 req: '0,
309 scramble_en: '0,
310 ecc_en: '0,
311 he_en: '0,
312 rd: '0,
313 prog: '0,
314 pg_erase: '0,
315 bk_erase: '0,
316 erase_suspend: '0,
317 part: FlashPartData,
318 info_sel: '0,
319 addr: '0,
320 prog_data: '0,
321 prog_last: '0,
322 prog_type: FlashProgNormal,
323 region_cfgs: '0,
324 addr_key: RndCnstAddrKeyDefault,
325 data_key: RndCnstDataKeyDefault,
Timothy Chen6e495182020-12-28 16:16:35 -0800326 rd_buf_en: 1'b0,
Timothy Chen16741102021-01-15 17:32:13 -0800327 tl_flash_c2p: '0,
328 alert_trig: 1'b0,
329 alert_ack: 1'b0
Timothy Chenff4a7702020-10-27 15:08:53 -0700330 };
331
332 // memory to flash controller
333 typedef struct packed {
334 logic [ProgTypes-1:0] prog_type_avail;
335 logic rd_done;
336 logic prog_done;
337 logic erase_done;
338 logic rd_err;
339 logic [BusWidth-1:0] rd_data;
340 logic init_busy;
Timothy Chen6e495182020-12-28 16:16:35 -0800341 tlul_pkg::tl_d2h_t tl_flash_p2c;
Timothy Chen16741102021-01-15 17:32:13 -0800342 logic flash_err;
343 logic flash_alert_p;
344 logic flash_alert_n;
345 logic [NumBanks-1:0] ecc_single_err;
346 logic [NumBanks-1:0] ecc_multi_err;
347 logic [NumBanks-1:0][BusAddrW-1:0] ecc_addr;
Timothy Chenff4a7702020-10-27 15:08:53 -0700348 } flash_rsp_t;
349
350 // default value of flash_rsp_t (for dangling ports)
351 parameter flash_rsp_t FLASH_RSP_DEFAULT = '{
Timothy Chen7d051eb2020-12-11 14:06:43 -0800352 prog_type_avail: '{default: '1},
353 rd_done: 1'b0,
354 prog_done: 1'b0,
355 erase_done: 1'b0,
356 rd_err: '0,
357 rd_data: '0,
358 init_busy: 1'b0,
Timothy Chen16741102021-01-15 17:32:13 -0800359 tl_flash_p2c: '0,
360 flash_err: 1'b0,
361 flash_alert_p: 1'b0,
362 flash_alert_n: 1'b1,
363 ecc_single_err: '0,
364 ecc_multi_err: '0,
365 ecc_addr: '0
Timothy Chenff4a7702020-10-27 15:08:53 -0700366 };
367
Timothy Chend39402a2020-12-15 20:34:09 -0800368 // RMA entries
Timothy Chenff4a7702020-10-27 15:08:53 -0700369 typedef struct packed {
Timothy Chend39402a2020-12-15 20:34:09 -0800370 logic [BankW-1:0] bank;
371 flash_part_e part;
372 logic [InfoTypesWidth-1:0] info_sel;
373 logic [PageW:0] start_page;
374 logic [PageW:0] num_pages;
375 } rma_wipe_entry_t;
Timothy Chenff4a7702020-10-27 15:08:53 -0700376
Timothy Chend39402a2020-12-15 20:34:09 -0800377 // entries to be wiped
378 parameter int WipeEntries = 3;
379 parameter rma_wipe_entry_t RmaWipeEntries[WipeEntries] = '{
380 '{
381 bank: SeedBank,
382 part: FlashPartInfo,
383 info_sel: SeedInfoSel,
384 start_page: OwnerInfoPage,
385 num_pages: 1
386 },
387
388 '{
389 bank: 0,
390 part: FlashPartData,
391 info_sel: 0,
392 start_page: 0,
393 num_pages: PagesPerBank
394 },
395
396 '{
397 bank: 1,
398 part: FlashPartData,
399 info_sel: 0,
400 start_page: 0,
401 num_pages: PagesPerBank
402 }
403 };
404
Timothy Chenff4a7702020-10-27 15:08:53 -0700405
406 // flash_ctrl to keymgr
407 typedef struct packed {
408 logic [NumSeeds-1:0][SeedWidth-1:0] seeds;
409 } keymgr_flash_t;
410
Timothy Chen65e16672020-12-05 09:17:14 -0800411 parameter keymgr_flash_t KEYMGR_FLASH_DEFAULT = '{
412 seeds: '{
413 256'h9152e32c9380a4bcc3e0ab263581e6b0e8825186e1e445631646e8bef8c45d47,
414 256'hfa365df52da48cd752fb3a026a8e608f0098cfe5fa9810494829d0cd9479eb78
415 }
416 };
417
Timothy Chenc0bed202020-11-19 18:18:46 -0800418 // dft_en jtag selection
419 typedef enum logic [2:0] {
420 FlashLcTckSel,
421 FlashLcTdiSel,
422 FlashLcTmsSel,
423 FlashLcTdoSel,
Timothy Chenb1ba59b2021-01-07 12:18:11 -0800424 FlashBistSel,
425 FlashLcDftLast
Timothy Chenc0bed202020-11-19 18:18:46 -0800426 } flash_lc_jtag_e;
Timothy Chenff4a7702020-10-27 15:08:53 -0700427
428 // find the max number pages among info types
429 function automatic integer max_info_pages(int infos[InfoTypes]);
430 int current_max = 0;
431 for (int i = 0; i < InfoTypes; i++) begin
432 if (infos[i] > current_max) begin
433 current_max = infos[i];
434 end
435 end
436 return current_max;
437 endfunction // max_info_banks
438
439
440endpackage : flash_ctrl_pkg