hw/ip/flash_ctrl/rtl/flash_prog_ctrl.sv Cov: 100%
1: // 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: // Faux Flash Prog Control
6: //
7:
8: module flash_prog_ctrl #(
9: parameter int AddrW = 10,
10: parameter int DataW = 32
11: ) (
12: input clk_i,
13: input rst_ni,
14:
15: // Software Interface
16: input op_start_i,
17: input [11:0] op_num_words_i,
18: output logic op_done_o,
19: output logic op_err_o,
20: input [AddrW-1:0] op_addr_i,
21:
22: // FIFO Interface
23: input data_rdy_i,
24: input [DataW-1:0] data_i,
25: output logic data_rd_o,
26:
27: // Flash Macro Interface
28: output logic flash_req_o,
29: output logic [AddrW-1:0] flash_addr_o,
30: output logic flash_ovfl_o,
31: output logic [DataW-1:0] flash_data_o,
32: input flash_done_i,
33: input flash_error_i
34: );
35:
36: typedef enum logic {
37: StNorm = 'h0,
38: StErr = 'h1
39: } state_e;
40:
41: state_e st, st_nxt;
42: logic [11:0] cnt, cnt_nxt;
43: logic cnt_hit;
44: logic [AddrW:0] int_addr;
45: logic txn_done;
46:
47:
48: always_ff @(posedge clk_i or negedge rst_ni) begin
49: if (!rst_ni) begin
50: cnt <= '0;
51: st <= StNorm;
52: end else begin
53: cnt <= cnt_nxt;
54: st <= st_nxt;
55: end
56: end
57:
58: assign txn_done = flash_req_o && flash_done_i;
59: assign cnt_hit = (cnt == op_num_words_i);
60:
61: // when error'd, continue to drain all program fifo contents like normal operation
62: // if this is not done, software may fill up the fifo without anyone
63: // draining the contents, leading to a lockup
64: always_comb begin
65: st_nxt = st;
66: cnt_nxt = cnt;
67: flash_req_o = 1'b0;
68: data_rd_o = 1'b0;
69: op_done_o = 1'b0;
70: op_err_o = 1'b0;
71:
72: unique case (st)
73: StNorm: begin
74: flash_req_o = op_start_i & data_rdy_i;
75:
76: if(txn_done && cnt_hit) begin
77: cnt_nxt = '0;
78: data_rd_o = 1'b1;
79: op_done_o = 1'b1;
80: op_err_o = flash_error_i;
81: end else if(txn_done) begin
82: cnt_nxt = cnt + 1'b1;
83: data_rd_o = 1'b1;
84: st_nxt = flash_error_i ? StErr : StNorm;
85: end
86: end
87: StErr: begin
88: data_rd_o = data_rdy_i;
89:
90: if (data_rdy_i && cnt_hit) begin
91: st_nxt = StNorm;
92: cnt_nxt = '0;
93: op_done_o = 1'b1;
94: op_err_o = 1'b1;
95: end else if (data_rdy_i) begin
96: cnt_nxt = cnt + 1'b1;
97: end
98: end
99: default:;
100: endcase // unique case (st)
101: end
102:
103: assign flash_data_o = data_i;
104: assign int_addr = op_addr_i + AddrW'(cnt);
105: assign flash_addr_o = int_addr[0 +: AddrW];
106: assign flash_ovfl_o = int_addr[AddrW];
107:
108: endmodule // flash_prog_ctrl
109: