../src/lowrisc_ip_flash_ctrl_0.1/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: