diff --git a/Bender.yml b/Bender.yml index 2ff83d4633..1c8ce431ad 100644 --- a/Bender.yml +++ b/Bender.yml @@ -9,7 +9,7 @@ package: dependencies: axi: { git: "https://github.com/pulp-platform/axi.git", version: 0.31.0 } common_cells: - { git: "https://github.com/pulp-platform/common_cells", version: 1.23.0 } + { git: "https://github.com/pulp-platform/common_cells", version: 1.35.0 } fpnew: { git: "https://github.com/pulp-platform/cvfpu.git", rev: pulp-v0.1.1 } tech_cells_generic: { git: "https://github.com/pulp-platform/tech_cells_generic.git", version: 0.2.13 } diff --git a/common/local/util/sram_pulp.sv b/common/local/util/sram_pulp.sv index f3c4773bf4..360b8c77eb 100644 --- a/common/local/util/sram_pulp.sv +++ b/common/local/util/sram_pulp.sv @@ -25,7 +25,7 @@ module sram #( parameter USER_WIDTH = 1, parameter USER_EN = 0, parameter NUM_WORDS = 1024, - parameter SIM_INIT = "none", + parameter SIM_INIT = "zeros", parameter OUT_REGS = 0 // enables output registers in FPGA macro (read lat = 2) )( input logic clk_i, diff --git a/core/ariane_regfile_ff.sv b/core/ariane_regfile_ff.sv index ae5cbeb0d7..fe3f417d82 100644 --- a/core/ariane_regfile_ff.sv +++ b/core/ariane_regfile_ff.sv @@ -31,6 +31,7 @@ module ariane_regfile #( // clock and reset input logic clk_i, input logic rst_ni, + input logic clear_i, // disable clock gates for testing input logic test_en_i, // read port @@ -63,14 +64,18 @@ module ariane_regfile #( if (~rst_ni) begin mem <= '{default: '0}; end else begin - for (int unsigned j = 0; j < CVA6Cfg.NrCommitPorts; j++) begin - for (int unsigned i = 0; i < NUM_WORDS; i++) begin - if (we_dec[j][i]) begin - mem[i] <= wdata_i[j]; + if (clear_i) begin + mem <= '{default: '0}; + end else begin + for (int unsigned j = 0; j < CVA6Cfg.NrCommitPorts; j++) begin + for (int unsigned i = 0; i < NUM_WORDS; i++) begin + if (we_dec[j][i]) begin + mem[i] <= wdata_i[j]; + end + end + if (ZERO_REG_ZERO) begin + mem[0] <= '0; end - end - if (ZERO_REG_ZERO) begin - mem[0] <= '0; end end end diff --git a/core/axi_shim.sv b/core/axi_shim.sv index 8e1cfa881d..128470d009 100644 --- a/core/axi_shim.sv +++ b/core/axi_shim.sv @@ -18,6 +18,7 @@ * */ +`include "common_cells/registers.svh" module axi_shim #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, @@ -27,6 +28,7 @@ module axi_shim #( ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low + input logic clear_i, // Synchronous clear active high // read channel // request input logic rd_req_i, @@ -283,16 +285,8 @@ module axi_shim #( // ---------------- // Registers // ---------------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - // start in flushing state and initialize the memory - wr_state_q <= IDLE; - wr_cnt_q <= '0; - end else begin - wr_state_q <= wr_state_d; - wr_cnt_q <= wr_cnt_d; - end - end + `FFARNC(wr_state_q, wr_state_d, clear_i, IDLE, clk_i, rst_ni) + `FFARNC(wr_cnt_q, wr_cnt_d, clear_i, '0, clk_i, rst_ni) // ---------------- // Assertions diff --git a/core/cache_subsystem/axi_adapter.sv b/core/cache_subsystem/axi_adapter.sv index 85852e9829..945eea0942 100644 --- a/core/cache_subsystem/axi_adapter.sv +++ b/core/cache_subsystem/axi_adapter.sv @@ -16,6 +16,8 @@ */ //import std_cache_pkg::*; +`include "common_cells/registers.svh" + module axi_adapter #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter int unsigned DATA_WIDTH = 256, @@ -24,9 +26,9 @@ module axi_adapter #( parameter type axi_req_t = logic, parameter type axi_rsp_t = logic ) ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low - + input logic clk_i, + input logic rst_ni, + input logic clear_i, output logic busy_o, input logic req_i, input ariane_pkg::ad_req_t type_i, @@ -461,28 +463,14 @@ module axi_adapter #( // ---------------- // Registers // ---------------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - // start in flushing state and initialize the memory - state_q <= IDLE; - cnt_q <= '0; - cache_line_q <= '0; - addr_offset_q <= '0; - id_q <= '0; - amo_q <= ariane_pkg::AMO_NONE; - size_q <= '0; - outstanding_aw_cnt_q <= '0; - end else begin - state_q <= state_d; - cnt_q <= cnt_d; - cache_line_q <= cache_line_d; - addr_offset_q <= addr_offset_d; - id_q <= id_d; - amo_q <= amo_d; - size_q <= size_d; - outstanding_aw_cnt_q <= outstanding_aw_cnt_d; - end - end + `FFARNC(state_q, state_d, clear_i, IDLE, clk_i, rst_ni) + `FFARNC(cnt_q, cnt_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(cache_line_q, cache_line_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(addr_offset_q, addr_offset_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(id_q, id_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(amo_q, amo_d, clear_i, ariane_pkg::AMO_NONE, clk_i, rst_ni) + `FFARNC(size_q, size_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(outstanding_aw_cnt_q, outstanding_aw_cnt_d, clear_i, '0, clk_i, rst_ni) function automatic axi_pkg::atop_t atop_from_amo(ariane_pkg::amo_t amo); axi_pkg::atop_t result = 6'b000000; diff --git a/core/cache_subsystem/cache_ctrl.sv b/core/cache_subsystem/cache_ctrl.sv index 3b876c4e52..0e88262c9a 100644 --- a/core/cache_subsystem/cache_ctrl.sv +++ b/core/cache_subsystem/cache_ctrl.sv @@ -17,6 +17,7 @@ // // Description: Cache controller +`include "common_cells/registers.svh" module cache_ctrl import ariane_pkg::*; @@ -26,6 +27,7 @@ module cache_ctrl ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low + input logic clear_i, // Synchronous clear active high input logic bypass_i, // enable cache output logic busy_o, input logic stall_i, // stall new memory requests @@ -442,17 +444,9 @@ module cache_ctrl // -------------- // Registers // -------------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - state_q <= IDLE; - mem_req_q <= '0; - hit_way_q <= '0; - end else begin - state_q <= state_d; - mem_req_q <= mem_req_d; - hit_way_q <= hit_way_d; - end - end + `FFARNC(state_q, state_d, clear_i, IDLE, clk_i, rst_ni) + `FFARNC(mem_req_q, mem_req_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(hit_way_q, hit_way_d, clear_i, '0, clk_i, rst_ni) //pragma translate_off `ifndef VERILATOR diff --git a/core/cache_subsystem/cva6_hpdcache_if_adapter.sv b/core/cache_subsystem/cva6_hpdcache_if_adapter.sv index f3a1d2e040..729ababd0b 100644 --- a/core/cache_subsystem/cva6_hpdcache_if_adapter.sv +++ b/core/cache_subsystem/cva6_hpdcache_if_adapter.sv @@ -9,6 +9,9 @@ // Authors: Cesar Fuguet // Date: February, 2023 // Description: Interface adapter for the CVA6 core + +`include "common_cells/registers.svh" + module cva6_hpdcache_if_adapter import hpdcache_pkg::*; @@ -26,6 +29,7 @@ module cva6_hpdcache_if_adapter // Clock and active-low reset pins input logic clk_i, input logic rst_ni, + input logic clear_i, // Port ID input hpdcache_pkg::hpdcache_req_sid_t hpdcache_req_sid_i, @@ -108,7 +112,7 @@ module cva6_hpdcache_if_adapter logic [ 7:0] amo_data_be; hpdcache_req_op_t amo_op; logic [31:0] amo_resp_word; - logic amo_pending_q; + logic amo_pending_q, amo_pending_n; // AMO logic // {{{ @@ -195,16 +199,13 @@ module cva6_hpdcache_if_adapter : hpdcache_rsp_i.rdata[0]; // }}} - always_ff @(posedge clk_i or negedge rst_ni) begin : amo_pending_ff - if (!rst_ni) begin - amo_pending_q <= 1'b0; - end else begin - amo_pending_q <= + assign amo_pending_n = ( cva6_amo_req_i.req & hpdcache_req_ready_i & ~amo_pending_q) | (~cva6_amo_resp_o.ack & amo_pending_q); - end - end + + `FFARNC(amo_pending_q, amo_pending_n, clear_i, 1'b0, clk_i, rst_ni) end + // }}} endgenerate // }}} diff --git a/core/cache_subsystem/cva6_hpdcache_subsystem.sv b/core/cache_subsystem/cva6_hpdcache_subsystem.sv index 16503c756d..9835bf8e53 100644 --- a/core/cache_subsystem/cva6_hpdcache_subsystem.sv +++ b/core/cache_subsystem/cva6_hpdcache_subsystem.sv @@ -109,6 +109,7 @@ module cva6_hpdcache_subsystem ) i_cva6_icache ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (1'b0), .flush_i (icache_flush_i), .en_i (icache_en_i), .miss_o (icache_miss_o), @@ -226,6 +227,7 @@ module cva6_hpdcache_subsystem ) i_cva6_hpdcache_load_if_adapter ( .clk_i, .rst_ni, + .clear_i('0), .hpdcache_req_sid_i(hpdcache_pkg::hpdcache_req_sid_t'(r)), @@ -252,6 +254,7 @@ module cva6_hpdcache_subsystem ) i_cva6_hpdcache_store_if_adapter ( .clk_i, .rst_ni, + .clear_i('0), .hpdcache_req_sid_i(hpdcache_pkg::hpdcache_req_sid_t'(NumPorts - 1)), @@ -278,6 +281,7 @@ module cva6_hpdcache_subsystem ) i_cva6_hpdcache_cmo_if_adapter ( .clk_i, .rst_ni, + .clear_i('0), .dcache_req_sid_i(hpdcache_pkg::hpdcache_req_sid_t'(NumPorts)), diff --git a/core/cache_subsystem/cva6_icache.sv b/core/cache_subsystem/cva6_icache.sv index 978c2720bf..9c1ba9a07d 100644 --- a/core/cache_subsystem/cva6_icache.sv +++ b/core/cache_subsystem/cva6_icache.sv @@ -24,6 +24,7 @@ // 3) NC accesses to I/O space are expected to return 32bit from memory. // +`include "common_cells/registers.svh" module cva6_icache import ariane_pkg::*; @@ -35,6 +36,7 @@ module cva6_icache ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, /// flush the icache, flush and kill have to be asserted together input logic flush_i, @@ -494,32 +496,16 @@ module cva6_icache ); end - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (!rst_ni) begin - cl_tag_q <= '0; - flush_cnt_q <= '0; - vaddr_q <= '0; - cmp_en_q <= '0; - cache_en_q <= '0; - flush_q <= '0; - state_q <= FLUSH; - cl_offset_q <= '0; - repl_way_oh_q <= '0; - inv_q <= '0; - end else begin - cl_tag_q <= cl_tag_d; - flush_cnt_q <= flush_cnt_d; - vaddr_q <= vaddr_d; - cmp_en_q <= cmp_en_d; - cache_en_q <= cache_en_d; - flush_q <= flush_d; - state_q <= state_d; - cl_offset_q <= cl_offset_d; - repl_way_oh_q <= repl_way_oh_d; - inv_q <= inv_d; - end - end + `FFARNC(cl_tag_q, cl_tag_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(flush_cnt_q, flush_cnt_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(vaddr_q, vaddr_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(cmp_en_q, cmp_en_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(cache_en_q, cache_en_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(flush_q, flush_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(state_q, state_d, clear_i, FLUSH, clk_i, rst_ni) + `FFARNC(cl_offset_q, cl_offset_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(repl_way_oh_q, repl_way_oh_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(inv_q, inv_d, clear_i, '0, clk_i, rst_ni) /////////////////////////////////////////////////////// // assertions @@ -559,10 +545,15 @@ module cva6_icache vld_mirror <= '{default: '0}; tag_mirror <= '{default: '0}; end else begin - for (int i = 0; i < ICACHE_SET_ASSOC; i++) begin - if (vld_req[i] & vld_we) begin - vld_mirror[vld_addr][i] <= vld_wdata[i]; - tag_mirror[vld_addr][i] <= cl_tag_q; + if (clear_i) begin + vld_mirror <= '{default: '0}; + tag_mirror <= '{default: '0}; + end else begin + for (int i = 0; i < ICACHE_SET_ASSOC; i++) begin + if (vld_req[i] & vld_we) begin + vld_mirror[vld_addr][i] <= vld_wdata[i]; + tag_mirror[vld_addr][i] <= cl_tag_q; + end end end end diff --git a/core/cache_subsystem/cva6_icache_axi_wrapper.sv b/core/cache_subsystem/cva6_icache_axi_wrapper.sv index 4561fc551f..a183b692aa 100644 --- a/core/cache_subsystem/cva6_icache_axi_wrapper.sv +++ b/core/cache_subsystem/cva6_icache_axi_wrapper.sv @@ -13,6 +13,8 @@ // Description: wrapper module to connect the L1I$ to a 64bit AXI bus. // +`include "common_cells/registers.svh" + module cva6_icache_axi_wrapper import ariane_pkg::*; import wt_cache_pkg::*; @@ -23,6 +25,7 @@ module cva6_icache_axi_wrapper ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, input riscv::priv_lvl_t priv_lvl_i, input logic flush_i, // flush the icache, flush and kill have to be asserted together @@ -109,6 +112,7 @@ module cva6_icache_axi_wrapper ) i_cva6_icache ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .flush_i (flush_i), .en_i (en_i), .miss_o (miss_o), @@ -137,6 +141,7 @@ module cva6_icache_axi_wrapper ) i_axi_shim ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .rd_req_i (axi_rd_req), .rd_gnt_o (axi_rd_gnt), .rd_addr_i (axi_rd_addr), @@ -191,18 +196,9 @@ module cva6_icache_axi_wrapper end // Registers - always_ff @(posedge clk_i or negedge rst_ni) begin : p_rd_buf - if (!rst_ni) begin - req_valid_q <= 1'b0; - req_data_q <= '0; - first_q <= 1'b1; - rd_shift_q <= '0; - end else begin - req_valid_q <= req_valid_d; - req_data_q <= req_data_d; - first_q <= first_d; - rd_shift_q <= rd_shift_d; - end - end + `FFARNC(req_valid_q, req_valid_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(req_data_q, req_data_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(first_q, first_d, clear_i, 1'b1, clk_i, rst_ni) + `FFARNC(rd_shift_q, rd_shift_d, clear_i, '0, clk_i, rst_ni) endmodule // cva6_icache_axi_wrapper diff --git a/core/cache_subsystem/miss_handler.sv b/core/cache_subsystem/miss_handler.sv index 0871ba88b6..e939d51d4d 100644 --- a/core/cache_subsystem/miss_handler.sv +++ b/core/cache_subsystem/miss_handler.sv @@ -16,6 +16,8 @@ // MISS Handler // -------------- +`include "common_cells/registers.svh" + module miss_handler import ariane_pkg::*; import std_cache_pkg::*; @@ -27,6 +29,7 @@ module miss_handler ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, output logic busy_o, // miss handler or axi is busy input logic flush_i, // flush request output logic flush_ack_o, // acknowledge successful flush @@ -505,23 +508,12 @@ module miss_handler // -------------------- // Sequential Process // -------------------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - mshr_q <= '0; - state_q <= INIT; - cnt_q <= '0; - evict_way_q <= '0; - evict_cl_q <= '0; - serve_amo_q <= 1'b0; - end else begin - mshr_q <= mshr_d; - state_q <= state_d; - cnt_q <= cnt_d; - evict_way_q <= evict_way_d; - evict_cl_q <= evict_cl_d; - serve_amo_q <= serve_amo_d; - end - end + `FFARNC(mshr_q, mshr_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(state_q, state_d, clear_i, INIT, clk_i, rst_ni) + `FFARNC(cnt_q, cnt_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(evict_way_q, evict_way_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(evict_cl_q, evict_cl_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(serve_amo_q, serve_amo_d, clear_i, '0, clk_i, rst_ni) //pragma translate_off `ifndef VERILATOR @@ -568,14 +560,15 @@ module miss_handler .req_t (bypass_req_t), .rsp_t (bypass_rsp_t) ) i_bypass_arbiter ( - .clk_i (clk_i), - .rst_ni(rst_ni), + .clk_i (clk_i), + .rst_ni (rst_ni), + .clear_i(clear_i), // Master Side - .req_i (bypass_ports_req), - .rsp_o (bypass_ports_rsp), + .req_i (bypass_ports_req), + .rsp_o (bypass_ports_rsp), // Slave Side - .req_o (bypass_adapter_req), - .rsp_i (bypass_adapter_rsp) + .req_o (bypass_adapter_req), + .rsp_i (bypass_adapter_rsp) ); // ---------------------- @@ -594,6 +587,7 @@ module miss_handler ) i_bypass_axi_adapter ( .clk_i(clk_i), .rst_ni(rst_ni), + .clear_i(clear_i), .busy_o(bypass_axi_busy), .req_i(bypass_adapter_req.req), .type_i(bypass_adapter_req.reqtype), @@ -630,6 +624,7 @@ module miss_handler ) i_miss_axi_adapter ( .clk_i, .rst_ni, + .clear_i, .busy_o (miss_axi_busy), .req_i (req_fsm_miss_valid), .type_i (req_fsm_miss_req), @@ -694,8 +689,9 @@ module axi_adapter_arbiter #( parameter type req_t = std_cache_pkg::bypass_req_t, parameter type rsp_t = std_cache_pkg::bypass_rsp_t ) ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low + input logic clk_i, + input logic rst_ni, + input logic clear_i, // Master ports input req_t [NR_PORTS-1:0] req_i, output rsp_t [NR_PORTS-1:0] rsp_o, @@ -798,19 +794,11 @@ module axi_adapter_arbiter #( endcase end - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - state_q <= IDLE; - sel_q <= '0; - req_q <= '0; - outstanding_cnt_q <= '0; - end else begin - state_q <= state_d; - sel_q <= sel_d; - req_q <= req_d; - outstanding_cnt_q <= outstanding_cnt_d; - end - end + `FFARNC(state_q, state_d, clear_i, IDLE, clk_i, rst_ni) + `FFARNC(sel_q, sel_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(req_q, req_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(outstanding_cnt_q, outstanding_cnt_d, clear_i, '0, clk_i, rst_ni) + // ------------ // Assertions // ------------ diff --git a/core/cache_subsystem/std_cache_subsystem.sv b/core/cache_subsystem/std_cache_subsystem.sv index 3695e50c23..79b237f64a 100644 --- a/core/cache_subsystem/std_cache_subsystem.sv +++ b/core/cache_subsystem/std_cache_subsystem.sv @@ -29,6 +29,7 @@ module std_cache_subsystem ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, input riscv::priv_lvl_t priv_lvl_i, output logic busy_o, input logic stall_i, // stall new memory requests @@ -82,6 +83,7 @@ module std_cache_subsystem ) i_cva6_icache_axi_wrapper ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .priv_lvl_i(priv_lvl_i), .flush_i (icache_flush_i), .en_i (icache_en_i), @@ -110,6 +112,7 @@ module std_cache_subsystem ) i_nbdcache ( .clk_i, .rst_ni, + .clear_i (clear_i), .enable_i (dcache_enable_i), .flush_i (dcache_flush_i), .flush_ack_o (dcache_flush_ack_o), diff --git a/core/cache_subsystem/std_nbdcache.sv b/core/cache_subsystem/std_nbdcache.sv index 5d904cf998..5db9788235 100644 --- a/core/cache_subsystem/std_nbdcache.sv +++ b/core/cache_subsystem/std_nbdcache.sv @@ -24,6 +24,7 @@ module std_nbdcache ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low + input logic clear_i, // Synchronous clear active high // Cache management input logic enable_i, // from CSR input logic flush_i, // high until acknowledged diff --git a/core/cache_subsystem/tag_cmp.sv b/core/cache_subsystem/tag_cmp.sv index a378c13b11..0cc4732d6a 100644 --- a/core/cache_subsystem/tag_cmp.sv +++ b/core/cache_subsystem/tag_cmp.sv @@ -15,6 +15,9 @@ // Description: Arbitrates access to cache memories, simplified request grant protocol // checks for hit or miss on cache // + +`include "common_cells/registers.svh" + module tag_cmp #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter int unsigned NR_PORTS = 3, @@ -25,6 +28,7 @@ module tag_cmp #( ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, input logic [NR_PORTS-1:0][DCACHE_SET_ASSOC-1:0] req_i, output logic [NR_PORTS-1:0] gnt_o, @@ -95,12 +99,6 @@ module tag_cmp #( `endif end - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - id_q <= 0; - end else begin - id_q <= id_d; - end - end + `FFARNC(id_q, id_d, clear_i, '0, clk_i, rst_ni) endmodule diff --git a/core/cache_subsystem/wt_axi_adapter.sv b/core/cache_subsystem/wt_axi_adapter.sv index 1647f1d072..cc606937b7 100644 --- a/core/cache_subsystem/wt_axi_adapter.sv +++ b/core/cache_subsystem/wt_axi_adapter.sv @@ -13,6 +13,7 @@ // Description: adapter module to connect the L1D$ and L1I$ to a 64bit AXI bus. // +`include "common_cells/registers.svh" module wt_axi_adapter import ariane_pkg::*; @@ -26,6 +27,7 @@ module wt_axi_adapter ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, // icache input logic icache_data_req_i, @@ -59,6 +61,7 @@ module wt_axi_adapter localparam MaxNumWords = $clog2(CVA6Cfg.AxiDataWidth / 8); localparam AxiRdBlenIcache = ariane_pkg::ICACHE_LINE_WIDTH / CVA6Cfg.AxiDataWidth - 1; localparam AxiRdBlenDcache = ariane_pkg::DCACHE_LINE_WIDTH / CVA6Cfg.AxiDataWidth - 1; + localparam dcache_in_t DcacheReturnTypeRstVal = wt_cache_pkg::DCACHE_LOAD_ACK; /////////////////////////////////////////////////////// // request path @@ -118,7 +121,7 @@ module wt_axi_adapter ) i_rr_arb_tree ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i('0), + .flush_i(clear_i), .rr_i ('0), .req_i (arb_req), .gnt_o (arb_ack), @@ -311,7 +314,7 @@ module wt_axi_adapter ) i_icache_data_fifo ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i (1'b0), + .flush_i (clear_i), .testmode_i(1'b0), .full_o (icache_data_full), .empty_o (icache_data_empty), @@ -328,7 +331,7 @@ module wt_axi_adapter ) i_dcache_data_fifo ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i (1'b0), + .flush_i (clear_i), .testmode_i(1'b0), .full_o (dcache_data_full), .empty_o (dcache_data_empty), @@ -352,7 +355,7 @@ module wt_axi_adapter ) i_rd_icache_id ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i (1'b0), + .flush_i (clear_i), .testmode_i(1'b0), .full_o (icache_rd_full), .empty_o (icache_rd_empty), @@ -369,7 +372,7 @@ module wt_axi_adapter ) i_rd_dcache_id ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i (1'b0), + .flush_i (clear_i), .testmode_i(1'b0), .full_o (dcache_rd_full), .empty_o (dcache_rd_empty), @@ -386,7 +389,7 @@ module wt_axi_adapter ) i_wr_dcache_id ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i (1'b0), + .flush_i (clear_i), .testmode_i(1'b0), .full_o (dcache_wr_full), .empty_o (dcache_wr_empty), @@ -416,7 +419,7 @@ module wt_axi_adapter ) i_b_fifo ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i (1'b0), + .flush_i (clear_i), .testmode_i(1'b0), .full_o (b_full), .empty_o (b_empty), @@ -619,39 +622,20 @@ module wt_axi_adapter // assign dcache_rtrn_o.inv.vld = '0; // assign dcache_rtrn_o.inv.all = '0; - always_ff @(posedge clk_i or negedge rst_ni) begin : p_rd_buf - if (!rst_ni) begin - icache_first_q <= 1'b1; - dcache_first_q <= 1'b1; - icache_rd_shift_q <= '0; - icache_rd_shift_user_q <= '0; - dcache_rd_shift_q <= '0; - dcache_rd_shift_user_q <= '0; - icache_rtrn_vld_q <= '0; - dcache_rtrn_vld_q <= '0; - icache_rtrn_tid_q <= '0; - dcache_rtrn_tid_q <= '0; - dcache_rtrn_type_q <= wt_cache_pkg::DCACHE_LOAD_ACK; - dcache_rtrn_inv_q <= '0; - amo_off_q <= '0; - amo_gen_r_q <= 1'b0; - end else begin - icache_first_q <= icache_first_d; - dcache_first_q <= dcache_first_d; - icache_rd_shift_q <= icache_rd_shift_d; - icache_rd_shift_user_q <= icache_rd_shift_user_d; - dcache_rd_shift_q <= dcache_rd_shift_d; - dcache_rd_shift_user_q <= dcache_rd_shift_user_d; - icache_rtrn_vld_q <= icache_rtrn_vld_d; - dcache_rtrn_vld_q <= dcache_rtrn_vld_d; - icache_rtrn_tid_q <= icache_rtrn_tid_d; - dcache_rtrn_tid_q <= dcache_rtrn_tid_d; - dcache_rtrn_type_q <= dcache_rtrn_type_d; - dcache_rtrn_inv_q <= dcache_rtrn_inv_d; - amo_off_q <= amo_off_d; - amo_gen_r_q <= amo_gen_r_d; - end - end + `FFARNC(icache_first_q, icache_first_d, clear_i, 1'b1, clk_i, rst_ni) + `FFARNC(dcache_first_q, dcache_first_d, clear_i, 1'b1, clk_i, rst_ni) + `FFARNC(icache_rd_shift_q, icache_rd_shift_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(icache_rd_shift_user_q, icache_rd_shift_user_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(dcache_rd_shift_q, dcache_rd_shift_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(dcache_rd_shift_user_q, dcache_rd_shift_user_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(icache_rtrn_vld_q, icache_rtrn_vld_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(dcache_rtrn_vld_q, dcache_rtrn_vld_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(icache_rtrn_tid_q, icache_rtrn_tid_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(dcache_rtrn_tid_q, dcache_rtrn_tid_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(dcache_rtrn_type_q, dcache_rtrn_type_d, clear_i, DcacheReturnTypeRstVal, clk_i, rst_ni) + `FFARNC(dcache_rtrn_inv_q, dcache_rtrn_inv_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(amo_off_q, amo_off_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(amo_gen_r_q, amo_gen_r_d, clear_i, '0, clk_i, rst_ni) /////////////////////////////////////////////////////// @@ -666,6 +650,7 @@ module wt_axi_adapter ) i_axi_shim ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .rd_req_i (axi_rd_req), .rd_gnt_o (axi_rd_gnt), .rd_addr_i (axi_rd_addr), diff --git a/core/cache_subsystem/wt_cache_subsystem.sv b/core/cache_subsystem/wt_cache_subsystem.sv index 14cd2395a1..c644b05966 100644 --- a/core/cache_subsystem/wt_cache_subsystem.sv +++ b/core/cache_subsystem/wt_cache_subsystem.sv @@ -30,6 +30,7 @@ module wt_cache_subsystem ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, output logic busy_o, input logic stall_i, // stall new memory requests input logic init_ni, @@ -91,6 +92,7 @@ module wt_cache_subsystem ) i_cva6_icache ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .flush_i (icache_flush_i), .en_i (icache_en_i), .miss_o (icache_miss_o), @@ -121,6 +123,7 @@ module wt_cache_subsystem ) i_wt_dcache ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .enable_i (dcache_enable_i), .busy_o (dcache_busy), .stall_i (stall_i), @@ -175,6 +178,7 @@ module wt_cache_subsystem ) i_adapter ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .icache_data_req_i(icache_adapter_data_req), .icache_data_ack_o(adapter_icache_data_ack), .icache_data_i (icache_adapter), diff --git a/core/cache_subsystem/wt_dcache.sv b/core/cache_subsystem/wt_dcache.sv index 6cc851687f..e0ee9cd02a 100644 --- a/core/cache_subsystem/wt_dcache.sv +++ b/core/cache_subsystem/wt_dcache.sv @@ -24,8 +24,8 @@ module wt_dcache parameter logic [CACHE_ID_WIDTH-1:0] RdAmoTxId = 1 ) ( input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low - + input logic rst_ni, // Asynchronous reset active low + input logic clear_i, // Synchronous clear active high // Cache management input logic enable_i, // from CSR input logic flush_i, // high until acknowledged @@ -129,6 +129,7 @@ module wt_dcache ) i_wt_dcache_missunit ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .enable_i (enable_i), .flush_i (flush_i), .flush_ack_o (flush_ack_o), @@ -191,6 +192,7 @@ module wt_dcache ) i_wt_dcache_ctrl ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .cache_en_i (cache_en), .busy_o (ctrl_busy[k]), .stall_i (stall_i), @@ -256,6 +258,7 @@ module wt_dcache ) i_wt_dcache_wbuffer ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .empty_o (wbuffer_empty_o), .not_ni_o (wbuffer_not_ni_o), // TODO: fix this @@ -314,6 +317,7 @@ module wt_dcache ) i_wt_dcache_mem ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), // read ports .rd_prio_i (rd_prio), .rd_tag_i (rd_tag), diff --git a/core/cache_subsystem/wt_dcache_ctrl.sv b/core/cache_subsystem/wt_dcache_ctrl.sv index a2e3fe38d1..aec54b0329 100644 --- a/core/cache_subsystem/wt_dcache_ctrl.sv +++ b/core/cache_subsystem/wt_dcache_ctrl.sv @@ -12,6 +12,7 @@ // Date: 13.09.2018 // Description: DCache controller for read port +`include "common_cells/registers.svh" module wt_dcache_ctrl import ariane_pkg::*; @@ -22,6 +23,7 @@ module wt_dcache_ctrl ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low + input logic clear_i, // Synchronous clear active high input logic cache_en_i, output logic busy_o, input logic stall_i, // stall new memory requests @@ -253,30 +255,15 @@ module wt_dcache_ctrl /////////////////////////////////////////////////////// // ff's /////////////////////////////////////////////////////// - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (!rst_ni) begin - state_q <= IDLE; - address_tag_q <= '0; - address_idx_q <= '0; - address_off_q <= '0; - id_q <= '0; - vld_data_q <= '0; - data_size_q <= '0; - rd_req_q <= '0; - rd_ack_q <= '0; - end else begin - state_q <= state_d; - address_tag_q <= address_tag_d; - address_idx_q <= address_idx_d; - address_off_q <= address_off_d; - id_q <= id_d; - vld_data_q <= vld_data_d; - data_size_q <= data_size_d; - rd_req_q <= rd_req_d; - rd_ack_q <= rd_ack_d; - end - end + `FFARNC(state_q, state_d, clear_i, IDLE, clk_i, rst_ni) + `FFARNC(address_tag_q, address_tag_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(address_idx_q, address_idx_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(address_off_q, address_off_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(id_q, id_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(vld_data_q, vld_data_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(data_size_q, data_size_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(rd_req_q, rd_req_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(rd_ack_q, rd_ack_d, clear_i, '0, clk_i, rst_ni) /////////////////////////////////////////////////////// // assertions diff --git a/core/cache_subsystem/wt_dcache_mem.sv b/core/cache_subsystem/wt_dcache_mem.sv index b2b41c3c73..c3920f314b 100644 --- a/core/cache_subsystem/wt_dcache_mem.sv +++ b/core/cache_subsystem/wt_dcache_mem.sv @@ -25,6 +25,7 @@ // 4) Read ports with same priority are RR arbited. but high prio ports (rd_prio_i[port_nr] = '1b1) will stall // low prio ports (rd_prio_i[port_nr] = '1b0) +`include "common_cells/registers.svh" module wt_dcache_mem import ariane_pkg::*; @@ -35,6 +36,7 @@ module wt_dcache_mem ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, // ports input logic [NumPorts-1:0][DCACHE_TAG_WIDTH-1:0] rd_tag_i, // tag in - comes one cycle later @@ -168,7 +170,7 @@ module wt_dcache_mem ) i_rr_arb_tree ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i('0), + .flush_i(clear_i), .rr_i ('0), .req_i (rd_req_masked), .gnt_o (rd_ack_o), @@ -340,19 +342,10 @@ module wt_dcache_mem ); end - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (!rst_ni) begin - bank_idx_q <= '0; - bank_off_q <= '0; - vld_sel_q <= '0; - cmp_en_q <= '0; - end else begin - bank_idx_q <= bank_idx_d; - bank_off_q <= bank_off_d; - vld_sel_q <= vld_sel_d; - cmp_en_q <= cmp_en_d; - end - end + `FFARNC(bank_idx_q, bank_idx_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(bank_off_q, bank_off_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(vld_sel_q, vld_sel_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(cmp_en_q, cmp_en_d, clear_i, '0, clk_i, rst_ni) /////////////////////////////////////////////////////// // assertions @@ -399,18 +392,11 @@ module wt_dcache_mem logic [ariane_pkg::DCACHE_TAG_WIDTH-1:0] tag_mirror[wt_cache_pkg::DCACHE_NUM_WORDS-1:0][ariane_pkg::DCACHE_SET_ASSOC-1:0]; logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] tag_write_duplicate_test; - always_ff @(posedge clk_i or negedge rst_ni) begin : p_mirror - if (!rst_ni) begin - vld_mirror <= '{default: '0}; - tag_mirror <= '{default: '0}; - end else begin - for (int i = 0; i < DCACHE_SET_ASSOC; i++) begin - if (vld_req[i] & vld_we) begin - vld_mirror[vld_addr][i] <= vld_wdata[i]; - tag_mirror[vld_addr][i] <= wr_cl_tag_i; - end - end - end + logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] load_enable; + for (genvar i = 0; i < ariane_pkg::DCACHE_SET_ASSOC; i++) begin : gen_p_mirror_registers + assign load_enable[i] = (vld_req[i] & vld_we) ? 1'b1 : 1'b0; + `FFLARNC(vld_mirror[vld_addr][i], vld_wdata[i], load_enable[i], clear_i, '0, clk_i, rst_ni) + `FFLARNC(tag_mirror[vld_addr][i], wr_cl_tag_i, load_enable[i], clear_i, '0, clk_i, rst_ni) end for (genvar i = 0; i < DCACHE_SET_ASSOC; i++) begin : gen_tag_dubl_test diff --git a/core/cache_subsystem/wt_dcache_missunit.sv b/core/cache_subsystem/wt_dcache_missunit.sv index 8cc3a4f154..61c725d1e6 100644 --- a/core/cache_subsystem/wt_dcache_missunit.sv +++ b/core/cache_subsystem/wt_dcache_missunit.sv @@ -13,6 +13,7 @@ // Description: miss controller for WT dcache. Note that the current assumption // is that the port with the highest index issues writes instead of reads. +`include "common_cells/registers.svh" module wt_dcache_missunit import ariane_pkg::*; @@ -24,6 +25,7 @@ module wt_dcache_missunit ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low + input logic clear_i, // Synchronous clear active high // cache management, signals from/to core input logic enable_i, // from CSR input logic flush_i, // flush request, this waits for pending tx (write, read) to finish and will clear the cache @@ -592,33 +594,17 @@ module wt_dcache_missunit // ff's /////////////////////////////////////////////////////// - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (!rst_ni) begin - state_q <= INIT; - cnt_q <= '0; - enable_q <= '0; - flush_ack_q <= '0; - mshr_vld_q <= '0; - mshr_vld_q1 <= '0; - mshr_q <= '0; - mshr_rdrd_collision_q <= '0; - miss_req_masked_q <= '0; - amo_req_q <= '0; - stores_inflight_q <= '0; - end else begin - state_q <= state_d; - cnt_q <= cnt_d; - enable_q <= enable_d; - flush_ack_q <= flush_ack_d; - mshr_vld_q <= mshr_vld_d; - mshr_vld_q1 <= mshr_vld_q; - mshr_q <= mshr_d; - mshr_rdrd_collision_q <= mshr_rdrd_collision_d; - miss_req_masked_q <= miss_req_masked_d; - amo_req_q <= amo_req_d; - stores_inflight_q <= stores_inflight_d; - end - end + `FFARNC(state_q, state_d, clear_i, INIT, clk_i, rst_ni) + `FFARNC(cnt_q, cnt_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(enable_q, enable_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(flush_ack_q, flush_ack_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(mshr_vld_q, mshr_vld_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(mshr_vld_q1, mshr_vld_q, clear_i, '0, clk_i, rst_ni) + `FFARNC(mshr_q, mshr_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(mshr_rdrd_collision_q, mshr_rdrd_collision_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(miss_req_masked_q, miss_req_masked_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(amo_req_q, amo_req_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(stores_inflight_q, stores_inflight_d, clear_i, '0, clk_i, rst_ni) /////////////////////////////////////////////////////// // assertions diff --git a/core/cache_subsystem/wt_dcache_wbuffer.sv b/core/cache_subsystem/wt_dcache_wbuffer.sv index 8e9c39d485..08c4b61702 100644 --- a/core/cache_subsystem/wt_dcache_wbuffer.sv +++ b/core/cache_subsystem/wt_dcache_wbuffer.sv @@ -48,6 +48,7 @@ // then, only the NC word is written into the write buffer and no further write requests are acknowledged until that // word has been evicted from the write buffer. +`include "common_cells/registers.svh" module wt_dcache_wbuffer import ariane_pkg::*; @@ -56,8 +57,8 @@ module wt_dcache_wbuffer parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low - + input logic rst_ni, // Asynchronous reset active low + input logic clear_i, // Synchronous clear active high input logic cache_en_i, // writes are treated as NC if disabled output logic empty_o, // asserted if no data is present in write buffer output logic not_ni_o, // asserted if no ni data is present in write buffer @@ -544,34 +545,17 @@ module wt_dcache_wbuffer // ff's /////////////////////////////////////////////////////// - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (!rst_ni) begin - wbuffer_q <= '{default: '0}; - tx_stat_q <= '{default: '0}; - ni_pending_q <= '0; - check_ptr_q <= '0; - check_ptr_q1 <= '0; - check_en_q <= '0; - check_en_q1 <= '0; - rd_tag_q <= '0; - rd_hit_oh_q <= '0; - wr_cl_vld_q <= '0; - wr_cl_idx_q <= '0; - end else begin - wbuffer_q <= wbuffer_d; - tx_stat_q <= tx_stat_d; - ni_pending_q <= ni_pending_d; - check_ptr_q <= check_ptr_d; - check_ptr_q1 <= check_ptr_q; - check_en_q <= check_en_d; - check_en_q1 <= check_en_q; - rd_tag_q <= rd_tag_d; - rd_hit_oh_q <= rd_hit_oh_d; - wr_cl_vld_q <= wr_cl_vld_d; - wr_cl_idx_q <= wr_cl_idx_d; - end - end - + `FFARNC(wbuffer_q, wbuffer_d, clear_i, '{default: '0}, clk_i, rst_ni) + `FFARNC(tx_stat_q, tx_stat_d, clear_i, '{default: '0}, clk_i, rst_ni) + `FFARNC(ni_pending_q, ni_pending_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(check_ptr_q, check_ptr_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(check_ptr_q1, check_ptr_q, clear_i, '0, clk_i, rst_ni) + `FFARNC(check_en_q, check_en_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(check_en_q1, check_en_q, clear_i, '0, clk_i, rst_ni) + `FFARNC(rd_tag_q, rd_tag_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(rd_hit_oh_q, rd_hit_oh_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(wr_cl_vld_q, wr_cl_vld_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(wr_cl_idx_q, wr_cl_idx_d, clear_i, '0, clk_i, rst_ni) /////////////////////////////////////////////////////// // assertions diff --git a/core/controller.sv b/core/controller.sv index b36b811efa..118622b6e4 100644 --- a/core/controller.sv +++ b/core/controller.sv @@ -12,6 +12,7 @@ // Date: 08.05.2017 // Description: Flush controller +`include "common_cells/registers.svh" module controller import ariane_pkg::*; @@ -22,6 +23,8 @@ module controller input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear, active high + input logic clear_i, // VS mode - CSR_REGFILE input logic v_i, // Reset microarchitecture - SUBSYSTEM @@ -379,8 +382,8 @@ module controller ) i_drain_cnt ( .clk_i, .rst_ni, - .clear_i (cache_busy_i), // Start counting from 0 when cache is busy - .en_i (drain_cnt != 4'hf), // Stop counting when saturated + .clear_i (cache_busy_i | clear_i), // Start counting from 0 when cache is busy + .en_i (drain_cnt != 4'hf), // Stop counting when saturated .load_i (1'b0), .down_i (1'b0), .d_i ('0), @@ -394,7 +397,7 @@ module controller ) i_pad_cnt ( .clk_i, .rst_ni, - .clear_i (1'b0), + .clear_i, .en_i (|pad_cnt), // Count until 0 .load_i (load_pad_cnt), // Start counting on positive edge of time irq .down_i (1'b1), // Always count down @@ -406,26 +409,13 @@ module controller // ---------------------- // Registers // ---------------------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - fence_t_state_q <= IDLE; - rst_uarch_cnt_q <= 4'b0; - fence_active_q <= 1'b0; - flush_dcache_o <= 1'b0; - rst_addr_q <= boot_addr_i; - time_irq_q <= 1'b0; - priv_lvl_q <= riscv::PRIV_LVL_M; - cache_init_q <= '0; - end else begin - fence_t_state_q <= fence_t_state_d; - fence_active_q <= fence_active_d; - rst_uarch_cnt_q <= rst_uarch_cnt_d; - // register on the flush signal, this signal might be critical - flush_dcache_o <= flush_dcache; - rst_addr_q <= rst_addr_d; - time_irq_q <= time_irq_i; - priv_lvl_q <= priv_lvl_i; - cache_init_q <= cache_init_d; - end - end + `FFARNC(fence_t_state_q, fence_t_state_d, clear_i, IDLE, clk_i, rst_ni) + `FFARNC(fence_active_q, fence_active_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(rst_uarch_cnt_q, rst_uarch_cnt_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(flush_dcache_o, flush_dcache, clear_i, '0, clk_i, rst_ni) + `FFARNC(rst_addr_q, rst_addr_d, clear_i, boot_addr_i, clk_i, rst_ni) + `FFARNC(time_irq_q, time_irq_i, clear_i, '0, clk_i, rst_ni) + `FFARNC(priv_lvl_q, priv_lvl_i, clear_i, riscv::PRIV_LVL_M, clk_i, rst_ni) + `FFARNC(cache_init_q, cache_init_d, clear_i, '0, clk_i, rst_ni) + endmodule diff --git a/core/csr_buffer.sv b/core/csr_buffer.sv index 8c93052b69..2501fc4943 100644 --- a/core/csr_buffer.sv +++ b/core/csr_buffer.sv @@ -13,6 +13,7 @@ // Description: Buffer to hold CSR address, this acts like a functional unit // to the scoreboard. +`include "common_cells/registers.svh" module csr_buffer import ariane_pkg::*; @@ -23,6 +24,8 @@ module csr_buffer input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // Flush CSR - CONTROLLER input logic flush_i, // FU data needed to execute instruction - ISSUE_STAGE @@ -71,12 +74,6 @@ module csr_buffer if (flush_i) csr_reg_n.valid = 1'b0; end // sequential process - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - csr_reg_q <= '{default: 0}; - end else begin - csr_reg_q <= csr_reg_n; - end - end + `FFARNC(csr_reg_q, csr_reg_n, clear_i, '{default: 0}, clk_i, rst_ni) endmodule diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index e87a7b654b..0a5b75b538 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -25,6 +25,8 @@ module csr_regfile input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high + input logic clear_i, // Timer threw a interrupt - SUBSYSTEM input logic time_irq_i, // send a flush request out when a CSR with a side effect changes - CONTROLLER @@ -857,6 +859,7 @@ module csr_regfile automatic riscv::hgatp_t hgatp; automatic logic [63:0] instret; + mask = '0; satp = satp_q; hgatp = hgatp_q; @@ -2497,97 +2500,186 @@ module csr_regfile end end end else begin - priv_lvl_q <= priv_lvl_d; - // floating-point registers - fcsr_q <= fcsr_d; - // debug signals - if (CVA6Cfg.DebugEn) begin - debug_mode_q <= debug_mode_d; - dcsr_q <= dcsr_d; - dpc_q <= dpc_d; - dscratch0_q <= dscratch0_d; - dscratch1_q <= dscratch1_d; - end - // machine mode registers - mstatus_q <= mstatus_d; - mtvec_rst_load_q <= 1'b0; - mtvec_q <= mtvec_d; - mip_q <= mip_d; - mie_q <= mie_d; - mintstatus_q <= mintstatus_d; - mintthresh_q <= mintthresh_d; - mepc_q <= mepc_d; - mcause_q <= mcause_d; - mcounteren_q <= mcounteren_d; - mtvt_q <= mtvt_d; - mscratch_q <= mscratch_d; - if (CVA6Cfg.TvalEn) mtval_q <= mtval_d; - fiom_q <= fiom_d; - dcache_q <= dcache_d; - icache_q <= icache_d; - mcountinhibit_q <= mcountinhibit_d; - acc_cons_q <= acc_cons_d; - fence_t_pad_q <= fence_t_pad_d; - fence_t_ceil_q <= fence_t_ceil_d; - // supervisor mode registers - if (CVA6Cfg.RVS) begin - medeleg_q <= medeleg_d; - mideleg_q <= mideleg_d; - sepc_q <= sepc_d; - scause_q <= scause_d; - stvec_q <= stvec_d; - scounteren_q <= scounteren_d; - sscratch_q <= sscratch_d; - if (CVA6Cfg.TvalEn) stval_q <= stval_d; - satp_q <= satp_d; - end - if (CVA6Cfg.RVH) begin - v_q <= v_d; - mtval2_q <= mtval2_d; - mtinst_q <= mtinst_d; - // hypervisor mode registers - hstatus_q <= hstatus_d; - hedeleg_q <= hedeleg_d; - hideleg_q <= hideleg_d; - hgeie_q <= hgeie_d; - hgatp_q <= hgatp_d; - hcounteren_q <= hcounteren_d; - htval_q <= htval_d; - htinst_q <= htinst_d; - // virtual supervisor mode registers - vsstatus_q <= vsstatus_d; - vsepc_q <= vsepc_d; - vscause_q <= vscause_d; - vstvec_q <= vstvec_d; - vsscratch_q <= vsscratch_d; - vstval_q <= vstval_d; - vsatp_q <= vsatp_d; - en_ld_st_g_translation_q <= en_ld_st_g_translation_d; - end - // timer and counters - cycle_q <= cycle_d; - instret_q <= instret_d; - // aux registers - en_ld_st_translation_q <= en_ld_st_translation_d; - // wait for interrupt - wfi_q <= wfi_d; - // pmp - for (int i = 0; i < 16; i++) begin - if (i < CVA6Cfg.NrPMPEntries) begin - // We only support >=8-byte granularity, NA4 is disabled - if(!CVA6Cfg.PMPEntryReadOnly[i] && pmpcfg_d[i].addr_mode != riscv::NA4 && !(pmpcfg_d[i].access_type.r == '0 && pmpcfg_d[i].access_type.w == '1)) begin - pmpcfg_q[i] <= pmpcfg_d[i]; + if (clear_i) begin + priv_lvl_q <= riscv::PRIV_LVL_M; + // floating-point registers + fcsr_q <= '0; + // debug signals + debug_mode_q <= 1'b0; + if (CVA6Cfg.DebugEn) begin + dcsr_q <= '0; + dcsr_q.prv <= riscv::PRIV_LVL_M; + dcsr_q.xdebugver <= 4'h4; + dpc_q <= '0; + dscratch0_q <= {riscv::XLEN{1'b0}}; + dscratch1_q <= {riscv::XLEN{1'b0}}; + end + // machine mode registers + mstatus_q <= 64'b0; + // set to boot address + direct mode + 4 byte offset which is the initial trap + mtvec_rst_load_q <= 1'b1; + mtvec_q <= '0; + mip_q <= {riscv::XLEN{1'b0}}; + mie_q <= {riscv::XLEN{1'b0}}; + mintstatus_q <= 32'b0; + mintthresh_q <= 8'b0; + mepc_q <= {riscv::XLEN{1'b0}}; + mcause_q <= {riscv::XLEN{1'b0}}; + mcounteren_q <= {riscv::XLEN{1'b0}}; + mtvt_q <= {riscv::XLEN{1'b0}}; + mscratch_q <= {riscv::XLEN{1'b0}}; + mtval_q <= {riscv::XLEN{1'b0}}; + fiom_q <= '0; + dcache_q <= {{riscv::XLEN - 1{1'b0}}, 1'b1}; + icache_q <= {{riscv::XLEN - 1{1'b0}}, 1'b1}; + mcountinhibit_q <= '0; + acc_cons_q <= {{riscv::XLEN - 1{1'b0}}, CVA6Cfg.EnableAccelerator}; + fence_t_pad_q <= {riscv::XLEN{1'b0}}; + fence_t_ceil_q <= {riscv::XLEN{1'b0}}; + // supervisor mode registers + if (CVA6Cfg.RVS) begin + medeleg_q <= {riscv::XLEN{1'b0}}; + mideleg_q <= {riscv::XLEN{1'b0}}; + sepc_q <= {riscv::XLEN{1'b0}}; + scause_q <= {riscv::XLEN{1'b0}}; + stvec_q <= {riscv::XLEN{1'b0}}; + scounteren_q <= {riscv::XLEN{1'b0}}; + sscratch_q <= {riscv::XLEN{1'b0}}; + stval_q <= {riscv::XLEN{1'b0}}; + satp_q <= {riscv::XLEN{1'b0}}; + end + if (CVA6Cfg.RVH) begin + v_q <= '0; + mtval2_q <= {riscv::XLEN{1'b0}}; + mtinst_q <= {riscv::XLEN{1'b0}}; + hstatus_q <= {riscv::XLEN{1'b0}}; + hedeleg_q <= {riscv::XLEN{1'b0}}; + hideleg_q <= {riscv::XLEN{1'b0}}; + hgeie_q <= {riscv::XLEN{1'b0}}; + hgatp_q <= {riscv::XLEN{1'b0}}; + hcounteren_q <= {riscv::XLEN{1'b0}}; + htval_q <= {riscv::XLEN{1'b0}}; + htinst_q <= {riscv::XLEN{1'b0}}; + // virtual supervisor mode registers + vsstatus_q <= 64'b0; + vsepc_q <= {riscv::XLEN{1'b0}}; + vscause_q <= {riscv::XLEN{1'b0}}; + vstvec_q <= {riscv::XLEN{1'b0}}; + vsscratch_q <= {riscv::XLEN{1'b0}}; + vstval_q <= {riscv::XLEN{1'b0}}; + vsatp_q <= {riscv::XLEN{1'b0}}; + en_ld_st_g_translation_q <= 1'b0; + end + // timer and counters + cycle_q <= 64'b0; + instret_q <= 64'b0; + // aux registers + en_ld_st_translation_q <= 1'b0; + // wait for interrupt + wfi_q <= 1'b0; + // pmp + for (int i = 0; i < 16; i++) begin + if (i < CVA6Cfg.NrPMPEntries) begin + pmpcfg_q[i] <= riscv::pmpcfg_t'(CVA6Cfg.PMPCfgRstVal[i]); + pmpaddr_q[i] <= CVA6Cfg.PMPAddrRstVal[i][riscv::PLEN-3:0]; end else begin - pmpcfg_q[i] <= pmpcfg_q[i]; + pmpcfg_q[i] <= '0; + pmpaddr_q[i] <= '0; end - if (!CVA6Cfg.PMPEntryReadOnly[i]) begin - pmpaddr_q[i] <= pmpaddr_d[i]; + end + end else begin + priv_lvl_q <= priv_lvl_d; + // floating-point registers + fcsr_q <= fcsr_d; + // debug signals + if (CVA6Cfg.DebugEn) begin + debug_mode_q <= debug_mode_d; + dcsr_q <= dcsr_d; + dpc_q <= dpc_d; + dscratch0_q <= dscratch0_d; + dscratch1_q <= dscratch1_d; + end + // machine mode registers + mstatus_q <= mstatus_d; + mtvec_rst_load_q <= 1'b0; + mtvec_q <= mtvec_d; + mip_q <= mip_d; + mie_q <= mie_d; + mintstatus_q <= mintstatus_d; + mintthresh_q <= mintthresh_d; + mepc_q <= mepc_d; + mcause_q <= mcause_d; + mcounteren_q <= mcounteren_d; + mtvt_q <= mtvt_d; + mscratch_q <= mscratch_d; + if (CVA6Cfg.TvalEn) mtval_q <= mtval_d; + fiom_q <= fiom_d; + dcache_q <= dcache_d; + icache_q <= icache_d; + mcountinhibit_q <= mcountinhibit_d; + acc_cons_q <= acc_cons_d; + fence_t_pad_q <= fence_t_pad_d; + fence_t_ceil_q <= fence_t_ceil_d; + // supervisor mode registers + if (CVA6Cfg.RVS) begin + medeleg_q <= medeleg_d; + mideleg_q <= mideleg_d; + sepc_q <= sepc_d; + scause_q <= scause_d; + stvec_q <= stvec_d; + scounteren_q <= scounteren_d; + sscratch_q <= sscratch_d; + if (CVA6Cfg.TvalEn) stval_q <= stval_d; + satp_q <= satp_d; + end + if (CVA6Cfg.RVH) begin + v_q <= v_d; + mtval2_q <= mtval2_d; + mtinst_q <= mtinst_d; + // hypervisor mode registers + hstatus_q <= hstatus_d; + hedeleg_q <= hedeleg_d; + hideleg_q <= hideleg_d; + hgeie_q <= hgeie_d; + hgatp_q <= hgatp_d; + hcounteren_q <= hcounteren_d; + htval_q <= htval_d; + htinst_q <= htinst_d; + // virtual supervisor mode registers + vsstatus_q <= vsstatus_d; + vsepc_q <= vsepc_d; + vscause_q <= vscause_d; + vstvec_q <= vstvec_d; + vsscratch_q <= vsscratch_d; + vstval_q <= vstval_d; + vsatp_q <= vsatp_d; + en_ld_st_g_translation_q <= en_ld_st_g_translation_d; + end + // timer and counters + cycle_q <= cycle_d; + instret_q <= instret_d; + // aux registers + en_ld_st_translation_q <= en_ld_st_translation_d; + // wait for interrupt + wfi_q <= wfi_d; + // pmp + for (int i = 0; i < 16; i++) begin + if (i < CVA6Cfg.NrPMPEntries) begin + // We only support >=8-byte granularity, NA4 is disabled + if(!CVA6Cfg.PMPEntryReadOnly[i] && pmpcfg_d[i].addr_mode != riscv::NA4 && !(pmpcfg_d[i].access_type.r == '0 && pmpcfg_d[i].access_type.w == '1)) begin + pmpcfg_q[i] <= pmpcfg_d[i]; + end else begin + pmpcfg_q[i] <= pmpcfg_q[i]; + end + if (!CVA6Cfg.PMPEntryReadOnly[i]) begin + pmpaddr_q[i] <= pmpaddr_d[i]; + end else begin + pmpaddr_q[i] <= pmpaddr_q[i]; + end end else begin - pmpaddr_q[i] <= pmpaddr_q[i]; + pmpcfg_q[i] <= '0; + pmpaddr_q[i] <= '0; end - end else begin - pmpcfg_q[i] <= '0; - pmpaddr_q[i] <= '0; end end end diff --git a/core/cva6.sv b/core/cva6.sv index 42285e1b02..321d4b17a2 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -12,6 +12,7 @@ // Date: 19.03.2017 // Description: CVA6 Top-level module +`include "common_cells/registers.svh" module cva6 import ariane_pkg::*; @@ -119,6 +120,8 @@ module cva6 input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high + input logic clear_i, // Reset boot address - SUBSYSTEM input logic [riscv::VLEN-1:0] boot_addr_i, // Hard ID reflected as CSR - SUBSYSTEM @@ -516,13 +519,7 @@ module cva6 logic inval_valid; logic inval_ready; - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - rst_uarch_n <= 1'b0; - end else begin - rst_uarch_n <= rst_uarch_controller_n; - end - end + `FFARNC(rst_uarch_n, rst_uarch_controller_n, clear_i, '0, clk_i, rst_ni) // ---------------------- // CLIC Controller <-> ID @@ -537,6 +534,7 @@ module cva6 .CVA6Cfg(CVA6ExtendCfg) ) i_frontend ( .rst_ni (rst_uarch_n), + .clear_i (clear_i), .flush_i (flush_ctrl_if), // not entirely correct .flush_bp_i (1'b0), .halt_i (halt_ctrl), @@ -566,6 +564,7 @@ module cva6 ) id_stage_i ( .clk_i, .rst_ni (rst_uarch_n), + .clear_i, .flush_i(flush_ctrl_if), .debug_req_i, @@ -673,6 +672,7 @@ module cva6 .clk_i, .rst_ni, .rst_uarch_ni (rst_uarch_n), + .clear_i (clear_i), .sb_full_o (sb_full), .flush_unissued_instr_i(flush_unissued_instr_ctrl_id), .flush_i (flush_ctrl_id), @@ -749,6 +749,7 @@ module cva6 ) ex_stage_i ( .clk_i(clk_i), .rst_ni(rst_uarch_n), + .clear_i(clear_i), .debug_mode_i(debug_mode), .flush_i(flush_ctrl_ex), .rs1_forwarding_i(rs1_forwarding_id_ex), @@ -1010,6 +1011,7 @@ module cva6 ) perf_counters_i ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .debug_mode_i (debug_mode), .addr_i (addr_csr_perf), .we_i (we_csr_perf), @@ -1134,6 +1136,7 @@ module cva6 // to D$ .clk_i (clk_i), .rst_ni (rst_uarch_n), + .clear_i (clear_i), .busy_o (busy_cache_ctrl), .stall_i (stall_ctrl_cache), .init_ni (init_ctrl_cache_n), @@ -1240,6 +1243,7 @@ module cva6 // to D$ .clk_i (clk_i), .rst_ni (rst_uarch_n), + .clear_i (clear_i), .priv_lvl_i (priv_lvl), .busy_o (busy_cache_ctrl), .stall_i (stall_ctrl_cache), @@ -1359,6 +1363,7 @@ module cva6 ) i_clic_controller ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), // from CSR file .priv_lvl_i (priv_lvl), .irq_ctrl_i (irq_ctrl_csr_id), @@ -1446,7 +1451,7 @@ module cva6 instr_tracer_if tracer_if (clk_i); // assign instruction tracer interface // control signals - assign tracer_if.rstn = rst_ni; + assign tracer_if.rstn = rst_ni & ~clear_i; assign tracer_if.flush_unissued = flush_unissued_instr_ctrl_id; assign tracer_if.flush = flush_ctrl_ex; // fetch @@ -1498,7 +1503,7 @@ module cva6 end always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin + if (~rst_ni | clear_i) begin cycles <= 0; end else begin byte mode = ""; diff --git a/core/cva6_clic_controller.sv b/core/cva6_clic_controller.sv index 68c6947cec..121591353f 100644 --- a/core/cva6_clic_controller.sv +++ b/core/cva6_clic_controller.sv @@ -4,11 +4,14 @@ // // Author: Nils Wistoff +`include "common_cells/registers.svh" + module cva6_clic_controller #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, // from CSR file input riscv::priv_lvl_t priv_lvl_i, // current privilege level input ariane_pkg::irq_ctrl_t irq_ctrl_i, @@ -88,11 +91,5 @@ module cva6_clic_controller #( // Acknowledge kill if no irq is inflight and irq is not accepted this cycle assign clic_kill_ack_o = clic_kill_req_i & ~irq_inflight_q & ~clic_irq_req_o; - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - irq_inflight_q <= 1'b0; - end else begin - irq_inflight_q <= irq_inflight_d; - end - end + `FFARNC(irq_inflight_q, irq_inflight_d, clear_i, '0, clk_i, rst_ni) endmodule diff --git a/core/cva6_rvfi.sv b/core/cva6_rvfi.sv index f6b63eb1db..694d4bcd97 100644 --- a/core/cva6_rvfi.sv +++ b/core/cva6_rvfi.sv @@ -8,6 +8,7 @@ // Original Author: Yannick Casamatta - Thales // Date: 09/01/2024 +`include "common_cells/registers.svh" module cva6_rvfi import ariane_pkg::*; @@ -19,6 +20,7 @@ module cva6_rvfi input logic clk_i, input logic rst_ni, + input logic clear_i, input rvfi_probes_t rvfi_probes_i, output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o @@ -204,13 +206,7 @@ module cva6_rvfi if (flush) issue_n.valid = 1'b0; end - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - issue_q <= '0; - end else begin - issue_q <= issue_n; - end - end + `FFARNC(issue_q, issue_n, clear_i, '0, clk_i, rst_ni) //ISSUE STAGE @@ -251,13 +247,7 @@ module cva6_rvfi end end - always_ff @(posedge clk_i or negedge rst_ni) begin : regs - if (!rst_ni) begin - mem_q <= '{default: sb_mem_t'(0)}; - end else begin - mem_q <= mem_n; - end - end + `FFARNC(mem_q, mem_n, clear_i, '{default: sb_mem_t'(0)}, clk_i, rst_ni) //---------------------------------------------------------------------------------------------------------- // PACK diff --git a/core/cvxif_example/cvxif_example_coprocessor.sv b/core/cvxif_example/cvxif_example_coprocessor.sv index 08e801c334..8026e3787a 100644 --- a/core/cvxif_example/cvxif_example_coprocessor.sv +++ b/core/cvxif_example/cvxif_example_coprocessor.sv @@ -9,12 +9,15 @@ // Example coprocessor adds rs1,rs2(,rs3) together and gives back the result to the CPU via the CoreV-X-Interface. // Coprocessor delays the sending of the result depending on result least significant bits. +`include "common_cells/registers.svh" + module cvxif_example_coprocessor import cvxif_pkg::*; import cvxif_instr_pkg::*; ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low + input logic clear_i, input cvxif_req_t cvxif_req_i, output cvxif_resp_t cvxif_resp_o ); @@ -100,13 +103,7 @@ module cvxif_example_coprocessor assign req_i.req = x_issue_req_i; assign req_i.resp = x_issue_resp_o; - always_ff @(posedge clk_i or negedge rst_ni) begin : regs - if (!rst_ni) begin - x_issue_ready_o <= 1; - end else begin - x_issue_ready_o <= x_issue_ready_q; - end - end + `FFARNC(x_issue_ready_o, x_issue_ready_q, clear_i, 1'b1, clk_i, rst_ni) fifo_v3 #( .FALL_THROUGH(1), //data_o ready and pop in the same cycle @@ -116,7 +113,7 @@ module cvxif_example_coprocessor ) fifo_commit_i ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i (1'b0), + .flush_i (clear_i), .testmode_i(1'b0), .full_o (fifo_full), .empty_o (fifo_empty), diff --git a/core/cvxif_fu.sv b/core/cvxif_fu.sv index d417552947..2ce49a8ef1 100644 --- a/core/cvxif_fu.sv +++ b/core/cvxif_fu.sv @@ -9,6 +9,7 @@ // Functional Unit for the logic of the CoreV-X-Interface +`include "common_cells/registers.svh" module cvxif_fu import ariane_pkg::*; @@ -19,6 +20,8 @@ module cvxif_fu input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // FU data needed to execute instruction - ISSUE_STAGE input fu_data_t fu_data_i, // Current privilege mode - CSR_REGFILE @@ -114,16 +117,8 @@ module cvxif_fu end end - always_ff @(posedge clk_i, negedge rst_ni) begin - if (~rst_ni) begin - illegal_q <= 1'b0; - illegal_id_q <= '0; - illegal_instr_q <= '0; - end else begin - illegal_q <= illegal_n; - illegal_id_q <= illegal_id_n; - illegal_instr_q <= illegal_instr_n; - end - end + `FFARNC(illegal_q, illegal_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(illegal_id_q, illegal_id_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(illegal_instr_q, illegal_instr_n, clear_i, '0, clk_i, rst_ni) endmodule diff --git a/core/ex_stage.sv b/core/ex_stage.sv index 3ca57340db..121c771a63 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -13,6 +13,7 @@ // Date: 19.04.2017 // Description: Instantiation of all functional units residing in the execute stage +`include "common_cells/registers.svh" module ex_stage import ariane_pkg::*; @@ -25,6 +26,8 @@ module ex_stage input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // Fetch flush request - CONTROLLER input logic flush_i, // Debug mode is enabled - CSR_REGFILE @@ -238,6 +241,8 @@ module ex_stage // instructions. + logic clear; + logic [5:0] load_enable; logic current_instruction_is_sfence_vma; logic current_instruction_is_hfence_vvma; logic current_instruction_is_hfence_gvma; @@ -256,6 +261,11 @@ module ex_stage logic [TRANS_ID_BITS-1:0] mult_trans_id; logic mult_valid; + // for reset values in flip flops + logic [ASID_WIDTH-1:0] asid_rs2_forwarding; + logic [VMID_WIDTH-1:0] vmid_rs2_forwarding; + logic [riscv::GPLEN-1:0] gpaddr_flush; + // 1. ALU (combinatorial) // data silence operation fu_data_t alu_data; @@ -301,6 +311,7 @@ module ex_stage ) csr_buffer_i ( .clk_i, .rst_ni, + .clear_i, .flush_i, .fu_data_i, .csr_valid_i, @@ -344,6 +355,7 @@ module ex_stage ) i_mult ( .clk_i, .rst_ni, + .clear_i, .flush_i, .mult_valid_i, .fu_data_i (mult_data), @@ -366,6 +378,7 @@ module ex_stage ) fpu_i ( .clk_i, .rst_ni, + .clear_i, .flush_i, .fpu_valid_i, .fpu_ready_o, @@ -402,6 +415,7 @@ module ex_stage ) lsu_i ( .clk_i, .rst_ni, + .clear_i, .flush_i, .stall_st_pending_i, .no_st_pending_o, @@ -471,6 +485,7 @@ module ex_stage ) cvxif_fu_i ( .clk_i, .rst_ni, + .clear_i, .fu_data_i, .priv_lvl_i(ld_st_priv_lvl_i), .x_valid_i, @@ -492,72 +507,40 @@ module ex_stage assign x_valid_o = '0; end + assign clear = flush_i | clear_i; + assign load_enable[0] = ((fu_data_i.operation == SFENCE_VMA && !v_i) && csr_valid_i) ? 1'b1 : 1'b0; + assign load_enable[1] = (((fu_data_i.operation == SFENCE_VMA && v_i) || fu_data_i.operation == HFENCE_VVMA) && csr_valid_i) ? 1'b1 : 1'b0; + assign load_enable[2] = ((fu_data_i.operation == HFENCE_GVMA) && csr_valid_i) ? 1'b1 : 1'b0; + assign load_enable[3] = (fu_data_i.operation == SFENCE_VMA && csr_valid_i) ? 1'b1 : 1'b0; + assign load_enable[4] = ((~(current_instruction_is_sfence_vma || current_instruction_is_hfence_vvma || current_instruction_is_hfence_gvma)) && (~((fu_data_i.operation == SFENCE_VMA || fu_data_i.operation == HFENCE_VVMA || fu_data_i.operation == HFENCE_GVMA ) && csr_valid_i))) ? 1'b1 : 1'b0; + assign load_enable[5] = ((~current_instruction_is_sfence_vma) && (~((fu_data_i.operation == SFENCE_VMA) && csr_valid_i))) ? 1'b1 : 1'b0; + if (CVA6Cfg.RVS) begin if (CVA6Cfg.RVH) begin - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - current_instruction_is_sfence_vma <= 1'b0; - current_instruction_is_hfence_vvma <= 1'b0; - current_instruction_is_hfence_gvma <= 1'b0; - end else begin - if (flush_i) begin - current_instruction_is_sfence_vma <= 1'b0; - current_instruction_is_hfence_vvma <= 1'b0; - current_instruction_is_hfence_gvma <= 1'b0; - end else if ((fu_data_i.operation == SFENCE_VMA && !v_i) && csr_valid_i) begin - current_instruction_is_sfence_vma <= 1'b1; - end else if (((fu_data_i.operation == SFENCE_VMA && v_i) || fu_data_i.operation == HFENCE_VVMA) && csr_valid_i) begin - current_instruction_is_hfence_vvma <= 1'b1; - end else if ((fu_data_i.operation == HFENCE_GVMA) && csr_valid_i) begin - current_instruction_is_hfence_gvma <= 1'b1; - end - end - end + `FFLARNC(current_instruction_is_sfence_vma, '1, load_enable[0], clear, '0, clk_i, rst_ni) + `FFLARNC(current_instruction_is_hfence_vvma, '1, load_enable[1], clear, '0, clk_i, rst_ni) + `FFLARNC(current_instruction_is_hfence_gvma, '1, load_enable[2], clear, '0, clk_i, rst_ni) end else begin assign current_instruction_is_hfence_vvma = 1'b0; assign current_instruction_is_hfence_gvma = 1'b0; - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - current_instruction_is_sfence_vma <= 1'b0; - end else begin - if (flush_i) begin - current_instruction_is_sfence_vma <= 1'b0; - end else if (fu_data_i.operation == SFENCE_VMA && csr_valid_i) begin - current_instruction_is_sfence_vma <= 1'b1; - end - end - end + `FFLARNC(current_instruction_is_sfence_vma, '1, load_enable[3], clear, '0, clk_i, rst_ni) end if (CVA6Cfg.RVH) begin + assign asid_rs2_forwarding = rs2_forwarding_i[ASID_WIDTH-1:0]; + assign vmid_rs2_forwarding = rs2_forwarding_i[VMID_WIDTH-1:0]; + assign gpaddr_flush = rs1_forwarding_i >> 2; // This process stores the rs1 and rs2 parameters of a SFENCE_VMA instruction. - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - vmid_to_be_flushed <= '0; - asid_to_be_flushed <= '0; - vaddr_to_be_flushed <= '0; - gpaddr_to_be_flushed <= '0; - // if the current instruction in EX_STAGE is a sfence.vma, in the next cycle no writes will happen - end else if ((~(current_instruction_is_sfence_vma || current_instruction_is_hfence_vvma || current_instruction_is_hfence_gvma)) && (~((fu_data_i.operation == SFENCE_VMA || fu_data_i.operation == HFENCE_VVMA || fu_data_i.operation == HFENCE_GVMA ) && csr_valid_i))) begin - vaddr_to_be_flushed <= rs1_forwarding_i; - gpaddr_to_be_flushed <= rs1_forwarding_i >> 2; - asid_to_be_flushed <= rs2_forwarding_i[ASID_WIDTH-1:0]; - vmid_to_be_flushed <= rs2_forwarding_i[VMID_WIDTH-1:0]; - end - end + `FFLARNC(vaddr_to_be_flushed, rs1_forwarding_i, load_enable[4], clear_i, '0, clk_i, rst_ni) + `FFLARNC(gpaddr_to_be_flushed, gpaddr_flush, load_enable[4], clear_i, '0, clk_i, rst_ni) + `FFLARNC(asid_to_be_flushed, asid_rs2_forwarding, load_enable[4], clear_i, '0, clk_i, rst_ni) + `FFLARNC(vmid_to_be_flushed, vmid_rs2_forwarding, load_enable[4], clear_i, '0, clk_i, rst_ni) end else begin assign vmid_to_be_flushed = '0; assign gpaddr_to_be_flushed = '0; + assign asid_rs2_forwarding = rs2_forwarding_i[ASID_WIDTH-1:0]; // This process stores the rs1 and rs2 parameters of a SFENCE_VMA instruction. - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - asid_to_be_flushed <= '0; - vaddr_to_be_flushed <= '0; - // if the current instruction in EX_STAGE is a sfence.vma, in the next cycle no writes will happen - end else if ((~current_instruction_is_sfence_vma) && (~((fu_data_i.operation == SFENCE_VMA) && csr_valid_i))) begin - vaddr_to_be_flushed <= rs1_forwarding_i; - asid_to_be_flushed <= rs2_forwarding_i[ASID_WIDTH-1:0]; - end - end + `FFLARNC(vaddr_to_be_flushed, rs1_forwarding_i, load_enable[5], clear_i, '0, clk_i, rst_ni) + `FFLARNC(asid_to_be_flushed, asid_rs2_forwarding, load_enable[5], clear_i, '0, clk_i, rst_ni) end end else begin assign current_instruction_is_sfence_vma = 1'b0; diff --git a/core/fpu_wrap.sv b/core/fpu_wrap.sv index d9ce6f86f3..daf944aab2 100644 --- a/core/fpu_wrap.sv +++ b/core/fpu_wrap.sv @@ -12,6 +12,7 @@ // Date: 12.04.2018 // Description: Wrapper for the floating-point unit +`include "common_cells/registers.svh" module fpu_wrap import ariane_pkg::*; @@ -20,6 +21,7 @@ module fpu_wrap ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, input logic flush_i, input logic fpu_valid_i, output logic fpu_ready_o, @@ -474,38 +476,19 @@ module fpu_wrap end // Buffer register and FSM state holding - always_ff @(posedge clk_i or negedge rst_ni) begin : fp_hold_reg - if (~rst_ni) begin - state_q <= READY; - operand_a_q <= '0; - operand_b_q <= '0; - operand_c_q <= '0; - fpu_op_q <= '0; - fpu_op_mod_q <= '0; - fpu_srcfmt_q <= '0; - fpu_dstfmt_q <= '0; - fpu_ifmt_q <= '0; - fpu_rm_q <= '0; - fpu_vec_op_q <= '0; - fpu_tag_q <= '0; - end else begin - state_q <= state_d; - // Hold register is [TRIGGERED] by FSM - if (hold_inputs) begin - operand_a_q <= operand_a_d; - operand_b_q <= operand_b_d; - operand_c_q <= operand_c_d; - fpu_op_q <= fpu_op_d; - fpu_op_mod_q <= fpu_op_mod_d; - fpu_srcfmt_q <= fpu_srcfmt_d; - fpu_dstfmt_q <= fpu_dstfmt_d; - fpu_ifmt_q <= fpu_ifmt_d; - fpu_rm_q <= fpu_rm_d; - fpu_vec_op_q <= fpu_vec_op_d; - fpu_tag_q <= fpu_tag_d; - end - end - end + `FFARNC(state_q, state_d, clear_i, READY, clk_i, rst_ni) + // Hold register is [TRIGGERED] by FSM + `FFLARNC(operand_a_q, operand_a_d, hold_inputs, clear_i, '0, clk_i, rst_ni) + `FFLARNC(operand_b_q, operand_b_d, hold_inputs, clear_i, '0, clk_i, rst_ni) + `FFLARNC(operand_c_q, operand_c_d, hold_inputs, clear_i, '0, clk_i, rst_ni) + `FFLARNC(fpu_op_q, fpu_op_d, hold_inputs, clear_i, '0, clk_i, rst_ni) + `FFLARNC(fpu_op_mod_q, fpu_op_mod_d, hold_inputs, clear_i, '0, clk_i, rst_ni) + `FFLARNC(fpu_srcfmt_q, fpu_srcfmt_d, hold_inputs, clear_i, '0, clk_i, rst_ni) + `FFLARNC(fpu_dstfmt_q, fpu_dstfmt_d, hold_inputs, clear_i, '0, clk_i, rst_ni) + `FFLARNC(fpu_ifmt_q, fpu_ifmt_d, hold_inputs, clear_i, '0, clk_i, rst_ni) + `FFLARNC(fpu_rm_q, fpu_rm_d, hold_inputs, clear_i, '0, clk_i, rst_ni) + `FFLARNC(fpu_vec_op_q, fpu_vec_op_d, hold_inputs, clear_i, '0, clk_i, rst_ni) + `FFLARNC(fpu_tag_q, fpu_tag_d, hold_inputs, clear_i, '0, clk_i, rst_ni) // Select FPU input data: from register if valid data in register, else directly from input assign operand_a = use_hold ? operand_a_q : operand_a_d; diff --git a/core/frontend/bht.sv b/core/frontend/bht.sv index e25724b0c4..c3799ed6ad 100644 --- a/core/frontend/bht.sv +++ b/core/frontend/bht.sv @@ -26,6 +26,8 @@ module bht #( input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // Fetch flush request - CONTROLLER input logic flush_i, // Debug mode state - CSR @@ -108,16 +110,24 @@ module bht #( end end end else begin - // evict all entries - if (flush_i) begin - for (int i = 0; i < NR_ROWS; i++) begin + if (clear_i) begin + for (int unsigned i = 0; i < NR_ROWS; i++) begin for (int j = 0; j < ariane_pkg::INSTR_PER_FETCH; j++) begin - bht_q[i][j].valid <= 1'b0; - bht_q[i][j].saturation_counter <= 2'b10; + bht_q[i][j] <= '0; end end end else begin - bht_q <= bht_d; + // evict all entries + if (flush_i) begin + for (int i = 0; i < NR_ROWS; i++) begin + for (int j = 0; j < ariane_pkg::INSTR_PER_FETCH; j++) begin + bht_q[i][j].valid <= 1'b0; + bht_q[i][j].saturation_counter <= 2'b10; + end + end + end else begin + bht_q <= bht_d; + end end end end diff --git a/core/frontend/btb.sv b/core/frontend/btb.sv index 52e2497ccd..a8810e7e0a 100644 --- a/core/frontend/btb.sv +++ b/core/frontend/btb.sv @@ -33,6 +33,8 @@ module btb #( input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // Fetch flush request - CONTROLLER input logic flush_i, // Debug mode state - CSR @@ -175,15 +177,19 @@ module btb #( // Bias the branches to be taken upon first arrival for (int i = 0; i < NR_ROWS; i++) btb_q[i] <= '{default: 0}; end else begin - // evict all entries - if (flush_i) begin - for (int i = 0; i < NR_ROWS; i++) begin - for (int j = 0; j < ariane_pkg::INSTR_PER_FETCH; j++) begin - btb_q[i][j].valid <= 1'b0; + if (clear_i) begin + for (int i = 0; i < NR_ROWS; i++) btb_q[i] <= '{default: 0}; + end else begin + // evict all entries + if (flush_i | clear_i) begin + for (int i = 0; i < NR_ROWS; i++) begin + for (int j = 0; j < ariane_pkg::INSTR_PER_FETCH; j++) begin + btb_q[i][j].valid <= 1'b0; + end end + end else begin + btb_q <= btb_d; end - end else begin - btb_q <= btb_d; end end end diff --git a/core/frontend/frontend.sv b/core/frontend/frontend.sv index e32b136fb4..0d6ff85a69 100644 --- a/core/frontend/frontend.sv +++ b/core/frontend/frontend.sv @@ -24,6 +24,8 @@ module frontend input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // Fetch flush request - CONTROLLER input logic flush_i, // flush branch prediction - zero @@ -132,6 +134,7 @@ module frontend ) i_instr_realign ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .flush_i (icache_dreq_o.kill_s2), .valid_i (icache_valid_q), .serving_unaligned_o(serving_unaligned), @@ -400,36 +403,51 @@ module frontend btb_q <= '0; bht_q <= '0; end else begin - npc_rst_load_q <= 1'b0; - npc_q <= npc_d; - speculative_q <= speculative_d; - icache_valid_q <= icache_dreq_i.valid; - if (icache_dreq_i.valid) begin - icache_data_q <= icache_data; - icache_vaddr_q <= icache_dreq_i.vaddr; - if (CVA6Cfg.RVH) begin - icache_gpaddr_q <= icache_dreq_i.ex.tval2[riscv::GPLEN-1:0]; - icache_tinst_q <= icache_dreq_i.ex.tinst; - icache_gva_q <= icache_dreq_i.ex.gva; - end else begin - icache_gpaddr_q <= 'b0; - icache_tinst_q <= 'b0; - icache_gva_q <= 1'b0; - end + if (clear_i) begin + npc_rst_load_q <= 1'b1; + npc_q <= '0; + speculative_q <= '0; + icache_data_q <= '0; + icache_valid_q <= 1'b0; + icache_vaddr_q <= 'b0; + icache_gpaddr_q <= 'b0; + icache_tinst_q <= 'b0; + icache_gva_q <= 1'b0; + icache_ex_valid_q <= ariane_pkg::FE_NONE; + btb_q <= '0; + bht_q <= '0; + end else begin + npc_rst_load_q <= 1'b0; + npc_q <= npc_d; + speculative_q <= speculative_d; + icache_valid_q <= icache_dreq_i.valid; + if (icache_dreq_i.valid) begin + icache_data_q <= icache_data; + icache_vaddr_q <= icache_dreq_i.vaddr; + if (CVA6Cfg.RVH) begin + icache_gpaddr_q <= icache_dreq_i.ex.tval2[riscv::GPLEN-1:0]; + icache_tinst_q <= icache_dreq_i.ex.tinst; + icache_gva_q <= icache_dreq_i.ex.gva; + end else begin + icache_gpaddr_q <= 'b0; + icache_tinst_q <= 'b0; + icache_gva_q <= 1'b0; + end - // Map the only three exceptions which can occur in the frontend to a two bit enum - if (ariane_pkg::MMU_PRESENT && icache_dreq_i.ex.cause == riscv::INSTR_GUEST_PAGE_FAULT) begin - icache_ex_valid_q <= ariane_pkg::FE_INSTR_GUEST_PAGE_FAULT; - end else if (ariane_pkg::MMU_PRESENT && icache_dreq_i.ex.cause == riscv::INSTR_PAGE_FAULT) begin - icache_ex_valid_q <= ariane_pkg::FE_INSTR_PAGE_FAULT; - end else if (icache_dreq_i.ex.cause == riscv::INSTR_ACCESS_FAULT) begin - icache_ex_valid_q <= ariane_pkg::FE_INSTR_ACCESS_FAULT; - end else begin - icache_ex_valid_q <= ariane_pkg::FE_NONE; + // Map the only three exceptions which can occur in the frontend to a two bit enum + if (ariane_pkg::MMU_PRESENT && icache_dreq_i.ex.cause == riscv::INSTR_GUEST_PAGE_FAULT) begin + icache_ex_valid_q <= ariane_pkg::FE_INSTR_GUEST_PAGE_FAULT; + end else if (ariane_pkg::MMU_PRESENT && icache_dreq_i.ex.cause == riscv::INSTR_PAGE_FAULT) begin + icache_ex_valid_q <= ariane_pkg::FE_INSTR_PAGE_FAULT; + end else if (icache_dreq_i.ex.cause == riscv::INSTR_ACCESS_FAULT) begin + icache_ex_valid_q <= ariane_pkg::FE_INSTR_ACCESS_FAULT; + end else begin + icache_ex_valid_q <= ariane_pkg::FE_NONE; + end + // save the uppermost prediction + btb_q <= btb_prediction[INSTR_PER_FETCH-1]; + bht_q <= bht_prediction[INSTR_PER_FETCH-1]; end - // save the uppermost prediction - btb_q <= btb_prediction[INSTR_PER_FETCH-1]; - bht_q <= bht_prediction[INSTR_PER_FETCH-1]; end end end @@ -443,6 +461,7 @@ module frontend ) i_ras ( .clk_i, .rst_ni, + .clear_i, .flush_i(flush_bp_i), .push_i (ras_push), .pop_i (ras_pop), @@ -465,6 +484,7 @@ module frontend ) i_btb ( .clk_i, .rst_ni, + .clear_i (clear_i), .flush_i (flush_bp_i), .debug_mode_i, .vpc_i (vpc_btb), @@ -482,6 +502,7 @@ module frontend ) i_bht ( .clk_i, .rst_ni, + .clear_i (clear_i), .flush_i (flush_bp_i), .debug_mode_i, .vpc_i (icache_vaddr_q), @@ -518,6 +539,7 @@ module frontend ) i_instr_queue ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .flush_i (flush_i), .instr_i (instr), // from re-aligner .addr_i (addr), // from re-aligner diff --git a/core/frontend/instr_queue.sv b/core/frontend/instr_queue.sv index a6658e7073..5bbfcf1b04 100644 --- a/core/frontend/instr_queue.sv +++ b/core/frontend/instr_queue.sv @@ -43,6 +43,8 @@ // the replay mechanism gets more complicated as it can be that a 32 bit instruction // can not be pushed at once. +`include "common_cells/registers.svh" + module instr_queue import ariane_pkg::*; #( @@ -52,6 +54,8 @@ module instr_queue input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // Fetch flush request - CONTROLLER input logic flush_i, // Instruction - instr_realign @@ -457,17 +461,24 @@ ariane_pkg::FETCH_FIFO_DEPTH pc_q <= '0; reset_address_q <= 1'b1; end else begin - pc_q <= pc_d; - reset_address_q <= reset_address_d; - if (flush_i) begin - // one-hot encoded + if (clear_i) begin idx_ds_q <= 'b1; - // binary encoded idx_is_q <= '0; + pc_q <= '0; reset_address_q <= 1'b1; end else begin - idx_ds_q <= idx_ds_d; - idx_is_q <= idx_is_d; + pc_q <= pc_d; + reset_address_q <= reset_address_d; + if (flush_i) begin + // one-hot encoded + idx_ds_q <= 'b1; + // binary encoded + idx_is_q <= '0; + reset_address_q <= 1'b1; + end else begin + idx_ds_q <= idx_ds_d; + idx_is_q <= idx_is_d; + end end end end @@ -479,10 +490,15 @@ ariane_pkg::FETCH_FIFO_DEPTH pc_q <= '0; reset_address_q <= 1'b1; end else begin - pc_q <= pc_d; - reset_address_q <= reset_address_d; - if (flush_i) begin + if (clear_i) begin + pc_q <= '0; reset_address_q <= 1'b1; + end else begin + pc_q <= pc_d; + reset_address_q <= reset_address_d; + if (flush_i) begin + reset_address_q <= 1'b1; + end end end end diff --git a/core/frontend/ras.sv b/core/frontend/ras.sv index cac8f3edc8..4b5597c3fe 100644 --- a/core/frontend/ras.sv +++ b/core/frontend/ras.sv @@ -14,6 +14,9 @@ // Date: 09.06.2018 // return address stack + +`include "common_cells/registers.svh" + module ras #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter int unsigned DEPTH = 2 @@ -22,6 +25,8 @@ module ras #( input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // Fetch flush request - CONTROLLER input logic flush_i, // Push address in RAS - FRONTEND @@ -68,11 +73,6 @@ module ras #( end end - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - stack_q <= '0; - end else begin - stack_q <= stack_d; - end - end + `FFARNC(stack_q, stack_d, clear_i, '0, clk_i, rst_ni) + endmodule diff --git a/core/id_stage.sv b/core/id_stage.sv index dcff46d078..792c390055 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -13,6 +13,8 @@ // Description: Instruction decode, contains the logic for decode, // issue and read operands. +`include "common_cells/registers.svh" + module id_stage #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( @@ -20,6 +22,8 @@ module id_stage #( input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // Fetch flush request - CONTROLLER input logic flush_i, // Debug (async) request - SUBSYSTEM @@ -178,11 +182,5 @@ module id_stage #( // ------------------------- // Registers (ID <-> Issue) // ------------------------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - issue_q <= '0; - end else begin - issue_q <= issue_n; - end - end + `FFARNC(issue_q, issue_n, clear_i, '0, clk_i, rst_ni) endmodule diff --git a/core/instr_realign.sv b/core/instr_realign.sv index 31a99a5561..6be7a86309 100644 --- a/core/instr_realign.sv +++ b/core/instr_realign.sv @@ -29,6 +29,8 @@ module instr_realign input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Syynchronous clear active high - SUBSYSTEM + input logic clear_i, // Fetch flush request - CONTROLLER input logic flush_i, // 32-bit block is valid - CACHE @@ -356,15 +358,21 @@ module instr_realign unaligned_address_q <= '0; unaligned_instr_q <= '0; end else begin - if (valid_i) begin - unaligned_address_q <= unaligned_address_d; - unaligned_instr_q <= unaligned_instr_d; - end + if (clear_i) begin + unaligned_q <= 1'b0; + unaligned_address_q <= '0; + unaligned_instr_q <= '0; + end else begin + if (valid_i) begin + unaligned_address_q <= unaligned_address_d; + unaligned_instr_q <= unaligned_instr_d; + end - if (flush_i) begin - unaligned_q <= 1'b0; - end else if (valid_i) begin - unaligned_q <= unaligned_d; + if (flush_i) begin + unaligned_q <= 1'b0; + end else if (valid_i) begin + unaligned_q <= unaligned_d; + end end end end diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index a09b148480..23d884cfb0 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -25,6 +25,8 @@ module issue_read_operands // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, input logic rst_uarch_ni, + // Synchronous clear active high + input logic clear_i, // Flush - CONTROLLER input logic flush_i, // Stall inserted by Acc dispatcher - ACC_DISPATCHER @@ -333,56 +335,67 @@ module issue_read_operands csr_valid_q <= 1'b0; branch_valid_q <= 1'b0; end else begin - alu_valid_q <= 1'b0; - lsu_valid_q <= 1'b0; - mult_valid_q <= 1'b0; - fpu_valid_q <= 1'b0; - fpu_fmt_q <= 2'b0; - fpu_rm_q <= 3'b0; - csr_valid_q <= 1'b0; - branch_valid_q <= 1'b0; - // Exception pass through: - // If an exception has occurred simply pass it through - // we do not want to issue this instruction - if (!issue_instr_i.ex.valid && issue_instr_valid_i && issue_ack_o) begin - case (issue_instr_i.fu) - ALU: begin - alu_valid_q <= 1'b1; - end - CTRL_FLOW: begin - branch_valid_q <= 1'b1; - end - MULT: begin - mult_valid_q <= 1'b1; - end - LOAD, STORE: begin - lsu_valid_q <= 1'b1; - end - CSR: begin - csr_valid_q <= 1'b1; - end - default: begin - if (issue_instr_i.fu == FPU && CVA6Cfg.FpPresent) begin - fpu_valid_q <= 1'b1; - fpu_fmt_q <= orig_instr.rftype.fmt; // fmt bits from instruction - fpu_rm_q <= orig_instr.rftype.rm; // rm bits from instruction - end else if (issue_instr_i.fu == FPU_VEC && CVA6Cfg.FpPresent) begin - fpu_valid_q <= 1'b1; - fpu_fmt_q <= orig_instr.rvftype.vfmt; // vfmt bits from instruction - fpu_rm_q <= {2'b0, orig_instr.rvftype.repl}; // repl bit from instruction - end - end - endcase - end - // if we got a flush request, de-assert the valid flag, otherwise we will start this - // functional unit with the wrong inputs - if (flush_i) begin + if (clear_i) begin + alu_valid_q <= '0; + lsu_valid_q <= '0; + mult_valid_q <= '0; + fpu_valid_q <= '0; + fpu_fmt_q <= '0; + fpu_rm_q <= '0; + csr_valid_q <= '0; + branch_valid_q <= '0; + end else begin alu_valid_q <= 1'b0; lsu_valid_q <= 1'b0; mult_valid_q <= 1'b0; fpu_valid_q <= 1'b0; + fpu_fmt_q <= 2'b0; + fpu_rm_q <= 3'b0; csr_valid_q <= 1'b0; branch_valid_q <= 1'b0; + // Exception pass through: + // If an exception has occurred simply pass it through + // we do not want to issue this instruction + if (!issue_instr_i.ex.valid && issue_instr_valid_i && issue_ack_o) begin + case (issue_instr_i.fu) + ALU: begin + alu_valid_q <= 1'b1; + end + CTRL_FLOW: begin + branch_valid_q <= 1'b1; + end + MULT: begin + mult_valid_q <= 1'b1; + end + LOAD, STORE: begin + lsu_valid_q <= 1'b1; + end + CSR: begin + csr_valid_q <= 1'b1; + end + default: begin + if (issue_instr_i.fu == FPU && CVA6Cfg.FpPresent) begin + fpu_valid_q <= 1'b1; + fpu_fmt_q <= orig_instr.rftype.fmt; // fmt bits from instruction + fpu_rm_q <= orig_instr.rftype.rm; // rm bits from instruction + end else if (issue_instr_i.fu == FPU_VEC && CVA6Cfg.FpPresent) begin + fpu_valid_q <= 1'b1; + fpu_fmt_q <= orig_instr.rvftype.vfmt; // vfmt bits from instruction + fpu_rm_q <= {2'b0, orig_instr.rvftype.repl}; // repl bit from instruction + end + end + endcase + end + // if we got a flush request, de-assert the valid flag, otherwise we will start this + // functional unit with the wrong inputs + if (flush_i) begin + alu_valid_q <= 1'b0; + lsu_valid_q <= 1'b0; + mult_valid_q <= 1'b0; + fpu_valid_q <= 1'b0; + csr_valid_q <= 1'b0; + branch_valid_q <= 1'b0; + end end end end @@ -393,20 +406,25 @@ module issue_read_operands cvxif_valid_q <= 1'b0; cvxif_off_instr_q <= 32'b0; end else begin - cvxif_valid_q <= 1'b0; - cvxif_off_instr_q <= 32'b0; - if (!issue_instr_i.ex.valid && issue_instr_valid_i && issue_ack_o) begin - case (issue_instr_i.fu) - CVXIF: begin - cvxif_valid_q <= 1'b1; - cvxif_off_instr_q <= orig_instr; - end - default: ; - endcase - end - if (flush_i) begin + if (clear_i) begin + cvxif_valid_q <= 1'b0; + cvxif_off_instr_q <= 32'b0; + end else begin cvxif_valid_q <= 1'b0; cvxif_off_instr_q <= 32'b0; + if (!issue_instr_i.ex.valid && issue_instr_valid_i && issue_ack_o) begin + case (issue_instr_i.fu) + CVXIF: begin + cvxif_valid_q <= 1'b1; + cvxif_off_instr_q <= orig_instr; + end + default: ; + endcase + end + if (flush_i) begin + cvxif_valid_q <= 1'b0; + cvxif_off_instr_q <= 32'b0; + end end end end @@ -508,6 +526,7 @@ module issue_read_operands .NR_READ_PORTS(CVA6Cfg.NrRgprPorts), .ZERO_REG_ZERO(1) ) i_ariane_regfile ( + .clear_i (clear_i), .test_en_i(1'b0), .raddr_i (raddr_pack), .rdata_o (rdata), @@ -557,6 +576,7 @@ module issue_read_operands .NR_READ_PORTS(3), .ZERO_REG_ZERO(0) ) i_ariane_fp_regfile ( + .clear_i (clear_i), .test_en_i(1'b0), .raddr_i (fp_raddr_pack), .rdata_o (fprdata), @@ -607,18 +627,33 @@ module issue_read_operands is_compressed_instr_o <= 1'b0; branch_predict_o <= {cf_t'(0), {riscv::VLEN{1'b0}}}; end else begin - operand_a_q <= operand_a_n; - operand_b_q <= operand_b_n; - imm_q <= imm_n; - fu_q <= fu_n; - operator_q <= operator_n; - trans_id_q <= trans_id_n; - if (CVA6Cfg.RVH) begin - tinst_q <= tinst_n; + if (clear_i) begin + operand_a_q <= '{default: 0}; + operand_b_q <= '{default: 0}; + imm_q <= '0; + fu_q <= NONE; + operator_q <= ADD; + trans_id_q <= '0; + if (CVA6Cfg.RVH) begin + tinst_q <= '0; + end + pc_o <= '0; + is_compressed_instr_o <= 1'b0; + branch_predict_o <= {cf_t'(0), {riscv::VLEN{1'b0}}}; + end else begin + operand_a_q <= operand_a_n; + operand_b_q <= operand_b_n; + imm_q <= imm_n; + fu_q <= fu_n; + operator_q <= operator_n; + trans_id_q <= trans_id_n; + if (CVA6Cfg.RVH) begin + tinst_q <= tinst_n; + end + pc_o <= issue_instr_i.pc; + is_compressed_instr_o <= issue_instr_i.is_compressed; + branch_predict_o <= issue_instr_i.bp; end - pc_o <= issue_instr_i.pc; - is_compressed_instr_o <= issue_instr_i.is_compressed; - branch_predict_o <= issue_instr_i.bp; end end diff --git a/core/issue_stage.sv b/core/issue_stage.sv index 29d12219a1..43bda3e00c 100644 --- a/core/issue_stage.sv +++ b/core/issue_stage.sv @@ -23,6 +23,8 @@ module issue_stage input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // Microreset active low - CONTROLLER input logic rst_uarch_ni, // Is scoreboard full - PERF_COUNTERS diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 04f222981b..b9252beb75 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -12,6 +12,7 @@ // Date: 19.04.2017 // Description: Load Store Unit, handles address calculation and memory interface signals +`include "common_cells/registers.svh" module load_store_unit import ariane_pkg::*; @@ -24,6 +25,8 @@ module load_store_unit input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // TO_BE_COMPLETED - TO_BE_COMPLETED input logic flush_i, // TO_BE_COMPLETED - TO_BE_COMPLETED @@ -328,17 +331,9 @@ module load_store_unit assign dtlb_ppn = mmu_vaddr_plen[riscv::PLEN-1:12]; assign dtlb_hit = 1'b1; - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - mmu_paddr <= '0; - translation_valid <= '0; - mmu_exception <= '0; - end else begin - mmu_paddr <= mmu_vaddr_plen; - translation_valid <= translation_req; - mmu_exception <= misaligned_exception; - end - end + `FFARNC(mmu_paddr, mmu_vaddr_plen, clear_i, '0, clk_i, rst_ni) + `FFARNC(translation_valid, translation_req, clear_i, '0, clk_i, rst_ni) + `FFARNC(mmu_exception, misaligned_exception, clear_i, '0, clk_i, rst_ni) end @@ -351,6 +346,7 @@ module load_store_unit ) i_store_unit ( .clk_i, .rst_ni, + .clear_i, .flush_i, .stall_st_pending_i, .no_st_pending_o, diff --git a/core/load_unit.sv b/core/load_unit.sv index b8c0861963..ca7a30aed6 100644 --- a/core/load_unit.sv +++ b/core/load_unit.sv @@ -18,6 +18,8 @@ // Modification: add support for multiple outstanding load operations // to the data cache +`include "common_cells/registers.svh" + module load_unit import ariane_pkg::*; #( @@ -27,6 +29,8 @@ module load_unit input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // TO_BE_COMPLETED - TO_BE_COMPLETED input logic flush_i, // Load unit input port - TO_BE_COMPLETED @@ -108,7 +112,7 @@ module load_unit logic [CVA6Cfg.NrLoadBufEntries-1:0] ldbuf_valid_q, ldbuf_valid_d; logic [CVA6Cfg.NrLoadBufEntries-1:0] ldbuf_flushed_q, ldbuf_flushed_d; - ldbuf_t [CVA6Cfg.NrLoadBufEntries-1:0] ldbuf_q; + ldbuf_t [CVA6Cfg.NrLoadBufEntries-1:0] ldbuf_q, ldbuf_en; logic ldbuf_empty, ldbuf_full; ldbuf_id_t ldbuf_free_index; logic ldbuf_w; @@ -142,6 +146,9 @@ module load_unit assign ldbuf_windex = (LDBUF_FALLTHROUGH && ldbuf_r) ? ldbuf_rindex : ldbuf_free_index; + for (genvar i = 0; i < CVA6Cfg.NrLoadBufEntries; i++) + assign ldbuf_en[i] = ((i == ldbuf_windex) & ldbuf_w) ? 1'b1 : 1'b0; + always_comb begin : ldbuf_comb ldbuf_flushed_d = ldbuf_flushed_q; ldbuf_valid_d = ldbuf_valid_q; @@ -162,21 +169,11 @@ module load_unit end end - always_ff @(posedge clk_i or negedge rst_ni) begin : ldbuf_ff - if (!rst_ni) begin - ldbuf_flushed_q <= '0; - ldbuf_valid_q <= '0; - ldbuf_last_id_q <= '0; - ldbuf_q <= '0; - end else begin - ldbuf_flushed_q <= ldbuf_flushed_d; - ldbuf_valid_q <= ldbuf_valid_d; - if (ldbuf_w) begin - ldbuf_last_id_q <= ldbuf_windex; - ldbuf_q[ldbuf_windex] <= ldbuf_wdata; - end - end - end + `FFARNC(ldbuf_flushed_q, ldbuf_flushed_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(ldbuf_valid_q, ldbuf_valid_d, clear_i, '0, clk_i, rst_ni) + `FFLARNC(ldbuf_last_id_q, ldbuf_windex, ldbuf_w, clear_i, '0, clk_i, rst_ni) + for (genvar i = 0; i < CVA6Cfg.NrLoadBufEntries; i++) + `FFLARNC(ldbuf_q[i], ldbuf_wdata, ldbuf_en[i], clear_i, '0, clk_i, rst_ni) // page offset is defined as the lower 12 bits, feed through for address checker assign page_offset_o = lsu_ctrl_i.vaddr[11:0]; @@ -448,13 +445,7 @@ module load_unit // latch physical address for the tag cycle (one cycle after applying the index) - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - state_q <= IDLE; - end else begin - state_q <= state_d; - end - end + `FFARNC(state_q, state_d, clear_i, IDLE, clk_i, rst_ni) // --------------- // Sign Extend diff --git a/core/lsu_bypass.sv b/core/lsu_bypass.sv index 5790c73a95..fd5940c961 100644 --- a/core/lsu_bypass.sv +++ b/core/lsu_bypass.sv @@ -23,6 +23,9 @@ // the LSU control should sample it and store it for later application to the units. It does so, by storing it in a // two element FIFO. This is necessary as we only know very late in the cycle whether the load/store will succeed (address check, // TLB hit mainly). So we better unconditionally allow another request to arrive and store this request in case we need to. + +`include "common_cells/registers.svh" + module lsu_bypass import ariane_pkg::*; #( @@ -32,6 +35,8 @@ module lsu_bypass input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // TO_BE_COMPLETED - TO_BE_COMPLETED input logic flush_i, @@ -114,18 +119,9 @@ module lsu_bypass end // registers - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - mem_q <= '0; - status_cnt_q <= '0; - write_pointer_q <= '0; - read_pointer_q <= '0; - end else begin - mem_q <= mem_n; - status_cnt_q <= status_cnt_n; - write_pointer_q <= write_pointer_n; - read_pointer_q <= read_pointer_n; - end - end + `FFARNC(mem_q, mem_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(status_cnt_q, status_cnt_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(write_pointer_q, write_pointer_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(read_pointer_q, read_pointer_n, clear_i, '0, clk_i, rst_ni) endmodule diff --git a/core/mmu_sv32/cva6_mmu_sv32.sv b/core/mmu_sv32/cva6_mmu_sv32.sv index 9c98793da4..2415fb84da 100644 --- a/core/mmu_sv32/cva6_mmu_sv32.sv +++ b/core/mmu_sv32/cva6_mmu_sv32.sv @@ -26,6 +26,8 @@ // 2020-02-17 0.1 S.Jacq MMU Sv32 for CV32A6 // =========================================================================== // +`include "common_cells/registers.svh" + module cva6_mmu_sv32 import ariane_pkg::*; #( @@ -36,6 +38,7 @@ module cva6_mmu_sv32 ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, input logic flush_i, input logic enable_translation_i, input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores @@ -119,6 +122,7 @@ module cva6_mmu_sv32 ) i_itlb ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i(clear_i), .flush_i(flush_tlb_i), .update_i(update_itlb), @@ -141,6 +145,7 @@ module cva6_mmu_sv32 ) i_dtlb ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i(clear_i), .flush_i(flush_tlb_i), .update_i(update_dtlb), @@ -164,6 +169,7 @@ module cva6_mmu_sv32 ) i_shared_tlb ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i(clear_i), .flush_i(flush_tlb_i), .enable_translation_i (enable_translation_i), @@ -203,6 +209,7 @@ module cva6_mmu_sv32 ) i_ptw ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i(clear_i), .flush_i(flush_i), .ptw_active_o (ptw_active), @@ -564,23 +571,11 @@ module cva6_mmu_sv32 // ---------- // Registers // ---------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - lsu_vaddr_q <= '0; - lsu_req_q <= '0; - misaligned_ex_q <= '0; - dtlb_pte_q <= '0; - dtlb_hit_q <= '0; - lsu_is_store_q <= '0; - dtlb_is_4M_q <= '0; - end else begin - lsu_vaddr_q <= lsu_vaddr_n; - lsu_req_q <= lsu_req_n; - misaligned_ex_q <= misaligned_ex_n; - dtlb_pte_q <= dtlb_pte_n; - dtlb_hit_q <= dtlb_hit_n; - lsu_is_store_q <= lsu_is_store_n; - dtlb_is_4M_q <= dtlb_is_4M_n; - end - end + `FFARNC(lsu_vaddr_q, lsu_vaddr_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(lsu_req_q, lsu_req_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(misaligned_ex_q, misaligned_ex_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_pte_q, dtlb_pte_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_hit_q, dtlb_hit_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(lsu_is_store_q, lsu_is_store_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_is_4M_q, dtlb_is_4M_n, clear_i, '0, clk_i, rst_ni) endmodule diff --git a/core/mmu_sv32/cva6_ptw_sv32.sv b/core/mmu_sv32/cva6_ptw_sv32.sv index 4bd736bd30..e41a3b43fc 100644 --- a/core/mmu_sv32/cva6_ptw_sv32.sv +++ b/core/mmu_sv32/cva6_ptw_sv32.sv @@ -26,6 +26,8 @@ /* verilator lint_off WIDTH */ +`include "common_cells/registers.svh" + module cva6_ptw_sv32 import ariane_pkg::*; #( @@ -34,6 +36,7 @@ module cva6_ptw_sv32 ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low + input logic clear_i, input logic flush_i, // flush everything, we need to do this because // actually everything we do is speculative at this stage // e.g.: there could be a CSR instruction that changes everything @@ -370,31 +373,16 @@ module cva6_ptw_sv32 end // sequential process - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - state_q <= IDLE; - is_instr_ptw_q <= 1'b0; - ptw_lvl_q <= LVL1; - tag_valid_q <= 1'b0; - tlb_update_asid_q <= '0; - vaddr_q <= '0; - ptw_pptr_q <= '0; - global_mapping_q <= 1'b0; - data_rdata_q <= '0; - data_rvalid_q <= 1'b0; - end else begin - state_q <= state_d; - ptw_pptr_q <= ptw_pptr_n; - is_instr_ptw_q <= is_instr_ptw_n; - ptw_lvl_q <= ptw_lvl_n; - tag_valid_q <= tag_valid_n; - tlb_update_asid_q <= tlb_update_asid_n; - vaddr_q <= vaddr_n; - global_mapping_q <= global_mapping_n; - data_rdata_q <= req_port_i.data_rdata; - data_rvalid_q <= req_port_i.data_rvalid; - end - end + `FFARNC(state_q, state_d, clear_i, IDLE, clk_i, rst_ni) + `FFARNC(ptw_pptr_q, ptw_pptr_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(is_instr_ptw_q, is_instr_ptw_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(ptw_lvl_q, ptw_lvl_n, clear_i, LVL1, clk_i, rst_ni) + `FFARNC(tag_valid_q, tag_valid_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(tlb_update_asid_q, tlb_update_asid_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(vaddr_q, vaddr_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(global_mapping_q, global_mapping_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(data_rdata_q, req_port_i.data_rdata, clear_i, '0, clk_i, rst_ni) + `FFARNC(data_rvalid_q, req_port_i.data_rvalid, clear_i, '0, clk_i, rst_ni) endmodule /* verilator lint_on WIDTH */ diff --git a/core/mmu_sv32/cva6_shared_tlb_sv32.sv b/core/mmu_sv32/cva6_shared_tlb_sv32.sv index 98e2a044a9..d457edf461 100644 --- a/core/mmu_sv32/cva6_shared_tlb_sv32.sv +++ b/core/mmu_sv32/cva6_shared_tlb_sv32.sv @@ -17,6 +17,8 @@ /* verilator lint_off WIDTH */ +`include "common_cells/registers.svh" + module cva6_shared_tlb_sv32 import ariane_pkg::*; #( @@ -25,9 +27,10 @@ module cva6_shared_tlb_sv32 parameter int SHARED_TLB_WAYS = 2, parameter int ASID_WIDTH = 1 ) ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low + input logic clk_i, + input logic rst_ni, input logic flush_i, + input logic clear_i, input logic enable_translation_i, // CSRs indicate to enable SV32 input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores @@ -229,33 +232,17 @@ module cva6_shared_tlb_sv32 end //tag_comparison // sequential process - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - itlb_vpn_q <= '0; - dtlb_vpn_q <= '0; - tlb_update_asid_q <= '0; - shared_tlb_access_q <= '0; - shared_tlb_vaddr_q <= '0; - shared_tag_valid_q <= '0; - vpn0_q <= '0; - vpn1_q <= '0; - itlb_req_q <= '0; - dtlb_req_q <= '0; - shared_tag_valid <= '0; - end else begin - itlb_vpn_q <= itlb_vaddr_i[riscv::SV-1:12]; - dtlb_vpn_q <= dtlb_vaddr_i[riscv::SV-1:12]; - tlb_update_asid_q <= tlb_update_asid_d; - shared_tlb_access_q <= shared_tlb_access_d; - shared_tlb_vaddr_q <= shared_tlb_vaddr_d; - shared_tag_valid_q <= shared_tag_valid_d; - vpn0_q <= vpn0_d; - vpn1_q <= vpn1_d; - itlb_req_q <= itlb_req_d; - dtlb_req_q <= dtlb_req_d; - shared_tag_valid <= shared_tag_valid_q[tag_rd_addr]; - end - end + `FFARNC(itlb_vpn_q, itlb_vaddr_i[riscv::SV-1:12], clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_vpn_q, dtlb_vaddr_i[riscv::SV-1:12], clear_i, '0, clk_i, rst_ni) + `FFARNC(tlb_update_asid_q, tlb_update_asid_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(shared_tlb_access_q, shared_tlb_access_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(shared_tlb_vaddr_q, shared_tlb_vaddr_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(shared_tag_valid_q, shared_tag_valid_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(vpn0_q, vpn0_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(vpn1_q, vpn1_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(itlb_req_q, itlb_req_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_req_q, dtlb_req_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(shared_tag_valid, shared_tag_valid_q[tag_rd_addr], clear_i, '0, clk_i, rst_ni) // ------------------ // Update and Flush diff --git a/core/mmu_sv32/cva6_tlb_sv32.sv b/core/mmu_sv32/cva6_tlb_sv32.sv index 79a7c98dc5..853aecbdb1 100644 --- a/core/mmu_sv32/cva6_tlb_sv32.sv +++ b/core/mmu_sv32/cva6_tlb_sv32.sv @@ -24,6 +24,8 @@ // 2020-02-17 0.1 S.Jacq TLB Sv32 for CV32A6 // =========================================================================== // +`include "common_cells/registers.svh" + module cva6_tlb_sv32 import ariane_pkg::*; #( @@ -33,6 +35,7 @@ module cva6_tlb_sv32 ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low + input logic clear_i, input logic flush_i, // Flush signal // Update TLB input tlb_update_sv32_t update_i, @@ -224,17 +227,10 @@ module cva6_tlb_sv32 end // sequential process - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - tags_q <= '{default: 0}; - content_q <= '{default: 0}; - plru_tree_q <= '{default: 0}; - end else begin - tags_q <= tags_n; - content_q <= content_n; - plru_tree_q <= plru_tree_n; - end - end + `FFARNC(tags_q, tags_n, clear_i, '{default: 0}, clk_i, rst_ni) + `FFARNC(content_q, content_n, clear_i, '{default: 0}, clk_i, rst_ni) + `FFARNC(plru_tree_q, plru_tree_n, clear_i, '{default: 0}, clk_i, rst_ni) + //-------------- // Sanity checks //-------------- diff --git a/core/mmu_sv39/mmu.sv b/core/mmu_sv39/mmu.sv index 56994f260d..eb410cd29a 100644 --- a/core/mmu_sv39/mmu.sv +++ b/core/mmu_sv39/mmu.sv @@ -14,6 +14,7 @@ // address translation unit. SV39 as defined in RISC-V // privilege specification 1.11-WIP +`include "common_cells/registers.svh" module mmu import ariane_pkg::*; @@ -25,6 +26,7 @@ module mmu ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, input logic flush_i, input logic enable_translation_i, input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores @@ -104,6 +106,7 @@ module mmu ) i_itlb ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i(clear_i), .flush_i(flush_tlb_i), .update_i(update_ptw_itlb), @@ -127,6 +130,7 @@ module mmu ) i_dtlb ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i(clear_i), .flush_i(flush_tlb_i), .update_i(update_ptw_dtlb), @@ -150,6 +154,7 @@ module mmu ) i_ptw ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .ptw_active_o (ptw_active), .walking_instr_o (walking_instr), .ptw_error_o (ptw_error), @@ -510,25 +515,12 @@ module mmu // ---------- // Registers // ---------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - lsu_vaddr_q <= '0; - lsu_req_q <= '0; - misaligned_ex_q <= '0; - dtlb_pte_q <= '0; - dtlb_hit_q <= '0; - lsu_is_store_q <= '0; - dtlb_is_2M_q <= '0; - dtlb_is_1G_q <= '0; - end else begin - lsu_vaddr_q <= lsu_vaddr_n; - lsu_req_q <= lsu_req_n; - misaligned_ex_q <= misaligned_ex_n; - dtlb_pte_q <= dtlb_pte_n; - dtlb_hit_q <= dtlb_hit_n; - lsu_is_store_q <= lsu_is_store_n; - dtlb_is_2M_q <= dtlb_is_2M_n; - dtlb_is_1G_q <= dtlb_is_1G_n; - end - end + `FFARNC(lsu_vaddr_q, lsu_vaddr_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(lsu_req_q, lsu_req_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(misaligned_ex_q, misaligned_ex_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_pte_q, dtlb_pte_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_hit_q, dtlb_hit_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(lsu_is_store_q, lsu_is_store_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_is_2M_q, dtlb_is_2M_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_is_1G_q, dtlb_is_1G_n, clear_i, '0, clk_i, rst_ni) endmodule diff --git a/core/mmu_sv39/ptw.sv b/core/mmu_sv39/ptw.sv index 2d0e3780ac..c8b1260ccb 100644 --- a/core/mmu_sv39/ptw.sv +++ b/core/mmu_sv39/ptw.sv @@ -15,6 +15,8 @@ /* verilator lint_off WIDTH */ +`include "common_cells/registers.svh" + module ptw import ariane_pkg::*; #( @@ -23,6 +25,7 @@ module ptw ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low + input logic clear_i, input logic flush_i, // flush everything, we need to do this because // actually everything we do is speculative at this stage // e.g.: there could be a CSR instruction that changes everything @@ -379,31 +382,16 @@ module ptw end // sequential process - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - state_q <= IDLE; - is_instr_ptw_q <= 1'b0; - ptw_lvl_q <= LVL1; - tag_valid_q <= 1'b0; - tlb_update_asid_q <= '0; - vaddr_q <= '0; - ptw_pptr_q <= '0; - global_mapping_q <= 1'b0; - data_rdata_q <= '0; - data_rvalid_q <= 1'b0; - end else begin - state_q <= state_d; - ptw_pptr_q <= ptw_pptr_n; - is_instr_ptw_q <= is_instr_ptw_n; - ptw_lvl_q <= ptw_lvl_n; - tag_valid_q <= tag_valid_n; - tlb_update_asid_q <= tlb_update_asid_n; - vaddr_q <= vaddr_n; - global_mapping_q <= global_mapping_n; - data_rdata_q <= req_port_i.data_rdata; - data_rvalid_q <= req_port_i.data_rvalid; - end - end + `FFARNC(state_q, state_d, clear_i, IDLE, clk_i, rst_ni) + `FFARNC(ptw_pptr_q, ptw_pptr_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(is_instr_ptw_q, is_instr_ptw_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(ptw_lvl_q, ptw_lvl_n, clear_i, LVL1, clk_i, rst_ni) + `FFARNC(tag_valid_q, tag_valid_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(tlb_update_asid_q, tlb_update_asid_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(vaddr_q, vaddr_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(global_mapping_q, global_mapping_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(data_rdata_q, req_port_i.data_rdata, clear_i, '0, clk_i, rst_ni) + `FFARNC(data_rvalid_q, req_port_i.data_rvalid, clear_i, '0, clk_i, rst_ni) endmodule /* verilator lint_on WIDTH */ diff --git a/core/mmu_sv39/tlb.sv b/core/mmu_sv39/tlb.sv index 3df2cb0173..cb4d130aaa 100644 --- a/core/mmu_sv39/tlb.sv +++ b/core/mmu_sv39/tlb.sv @@ -14,6 +14,7 @@ // Description: Translation Lookaside Buffer, SV39 // fully set-associative +`include "common_cells/registers.svh" module tlb import ariane_pkg::*; @@ -24,6 +25,7 @@ module tlb ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low + input logic clear_i, input logic flush_i, // Flush signal // Update TLB input tlb_update_t update_i, @@ -233,17 +235,9 @@ module tlb end // sequential process - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - tags_q <= '{default: 0}; - content_q <= '{default: 0}; - plru_tree_q <= '{default: 0}; - end else begin - tags_q <= tags_n; - content_q <= content_n; - plru_tree_q <= plru_tree_n; - end - end + `FFARNC(tags_q, tags_n, clear_i, '{default: 0}, clk_i, rst_ni) + `FFARNC(content_q, content_n, clear_i, '{default: 0}, clk_i, rst_ni) + `FFARNC(plru_tree_q, plru_tree_n, clear_i, '{default: 0}, clk_i, rst_ni) //-------------- // Sanity checks //-------------- diff --git a/core/mmu_sv39x4/cva6_mmu_sv39x4.sv b/core/mmu_sv39x4/cva6_mmu_sv39x4.sv index 041bf14fe6..19eabe6c6c 100644 --- a/core/mmu_sv39x4/cva6_mmu_sv39x4.sv +++ b/core/mmu_sv39x4/cva6_mmu_sv39x4.sv @@ -18,6 +18,7 @@ // This module is an adaptation of the MMU Sv39x4 developed // by Florian Zaruba to the Sv39x4 standard. +`include "common_cells/registers.svh" module cva6_mmu_sv39x4 import ariane_pkg::*; @@ -30,6 +31,7 @@ module cva6_mmu_sv39x4 ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, input logic flush_i, input logic enable_translation_i, input logic enable_g_translation_i, @@ -142,6 +144,7 @@ module cva6_mmu_sv39x4 ) i_itlb ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .flush_i (flush_tlb_i), .flush_vvma_i(flush_tlb_vvma_i), .flush_gvma_i(flush_tlb_gvma_i), @@ -176,6 +179,7 @@ module cva6_mmu_sv39x4 ) i_dtlb ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .flush_i (flush_tlb_i), .flush_vvma_i(flush_tlb_vvma_i), .flush_gvma_i(flush_tlb_gvma_i), @@ -683,33 +687,16 @@ module cva6_mmu_sv39x4 // ---------- // Registers // ---------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - lsu_vaddr_q <= '0; - lsu_gpaddr_q <= '0; - lsu_tinst_q <= '0; - hs_ld_st_inst_q <= '0; - lsu_req_q <= '0; - misaligned_ex_q <= '0; - dtlb_pte_q <= '0; - dtlb_gpte_q <= '0; - dtlb_hit_q <= '0; - lsu_is_store_q <= '0; - dtlb_is_2M_q <= '0; - dtlb_is_1G_q <= '0; - end else begin - lsu_vaddr_q <= lsu_vaddr_n; - lsu_gpaddr_q <= lsu_gpaddr_n; - lsu_tinst_q <= lsu_tinst_n; - hs_ld_st_inst_q <= hs_ld_st_inst_n; - lsu_req_q <= lsu_req_n; - misaligned_ex_q <= misaligned_ex_n; - dtlb_pte_q <= dtlb_pte_n; - dtlb_gpte_q <= dtlb_gpte_n; - dtlb_hit_q <= dtlb_hit_n; - lsu_is_store_q <= lsu_is_store_n; - dtlb_is_2M_q <= dtlb_is_2M_n; - dtlb_is_1G_q <= dtlb_is_1G_n; - end - end + `FFARNC(lsu_vaddr_q, lsu_vaddr_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(lsu_gpaddr_q, lsu_gpaddr_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(lsu_tinst_q, lsu_tinst_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(hs_ld_st_inst_q, hs_ld_st_inst_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(lsu_req_q, lsu_req_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(misaligned_ex_q, misaligned_ex_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_pte_q, dtlb_pte_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_gpte_q, dtlb_gpte_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_hit_q, dtlb_hit_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(lsu_is_store_q, lsu_is_store_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_is_2M_q, dtlb_is_2M_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(dtlb_is_1G_q, dtlb_is_1G_n, clear_i, '0, clk_i, rst_ni) endmodule diff --git a/core/mmu_sv39x4/cva6_ptw_sv39x4.sv b/core/mmu_sv39x4/cva6_ptw_sv39x4.sv index b645c2bc43..84acfcf249 100644 --- a/core/mmu_sv39x4/cva6_ptw_sv39x4.sv +++ b/core/mmu_sv39x4/cva6_ptw_sv39x4.sv @@ -19,6 +19,8 @@ /* verilator lint_off WIDTH */ +`include "common_cells/registers.svh" + module cva6_ptw_sv39x4 import ariane_pkg::*; #( @@ -28,6 +30,7 @@ module cva6_ptw_sv39x4 ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low + input logic clear_i, input logic flush_i, // flush everything, we need to do this because // actually everything we do is speculative at this stage // e.g.: there could be a CSR instruction that changes everything @@ -596,43 +599,22 @@ module cva6_ptw_sv39x4 end // sequential process - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - state_q <= IDLE; - ptw_stage_q <= S_STAGE; - is_instr_ptw_q <= 1'b0; - ptw_lvl_q <= LVL1; - gptw_lvl_q <= LVL1; - tag_valid_q <= 1'b0; - tlb_update_asid_q <= '0; - tlb_update_vmid_q <= '0; - vaddr_q <= '0; - gpaddr_q <= '0; - ptw_pptr_q <= '0; - gptw_pptr_q <= '0; - global_mapping_q <= 1'b0; - data_rdata_q <= '0; - gpte_q <= '0; - data_rvalid_q <= 1'b0; - end else begin - state_q <= state_d; - ptw_stage_q <= ptw_stage_d; - ptw_pptr_q <= ptw_pptr_n; - gptw_pptr_q <= gptw_pptr_n; - is_instr_ptw_q <= is_instr_ptw_n; - ptw_lvl_q <= ptw_lvl_n; - gptw_lvl_q <= gptw_lvl_n; - tag_valid_q <= tag_valid_n; - tlb_update_asid_q <= tlb_update_asid_n; - tlb_update_vmid_q <= tlb_update_vmid_n; - vaddr_q <= vaddr_n; - gpaddr_q <= gpaddr_n; - global_mapping_q <= global_mapping_n; - data_rdata_q <= req_port_i.data_rdata; - gpte_q <= gpte_d; - data_rvalid_q <= req_port_i.data_rvalid; - end - end + `FFARNC(state_q, state_d, clear_i, IDLE, clk_i, rst_ni) + `FFARNC(ptw_stage_q, ptw_stage_d, clear_i, S_STAGE, clk_i, rst_ni) + `FFARNC(is_instr_ptw_q, is_instr_ptw_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(ptw_lvl_q, ptw_lvl_n, clear_i, LVL1, clk_i, rst_ni) + `FFARNC(gptw_lvl_q, gptw_lvl_n, clear_i, LVL1, clk_i, rst_ni) + `FFARNC(tag_valid_q, tag_valid_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(tlb_update_asid_q, tlb_update_asid_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(tlb_update_vmid_q, tlb_update_vmid_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(vaddr_q, vaddr_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(gpaddr_q, gpaddr_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(ptw_pptr_q, ptw_pptr_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(gptw_pptr_q, gptw_pptr_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(global_mapping_q, global_mapping_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(data_rdata_q, req_port_i.data_rdata, clear_i, '0, clk_i, rst_ni) + `FFARNC(gpte_q, gpte_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(data_rvalid_q, req_port_i.data_rvalid, clear_i, '0, clk_i, rst_ni) endmodule /* verilator lint_on WIDTH */ diff --git a/core/mmu_sv39x4/cva6_tlb_sv39x4.sv b/core/mmu_sv39x4/cva6_tlb_sv39x4.sv index f9cf01cb18..c12a5104ee 100644 --- a/core/mmu_sv39x4/cva6_tlb_sv39x4.sv +++ b/core/mmu_sv39x4/cva6_tlb_sv39x4.sv @@ -16,6 +16,7 @@ // This module is an adaptation of the Sv39 TLB developed // by Florian Zaruba and David Schaffenrath to the Sv39x4 standard. +`include "common_cells/registers.svh" module cva6_tlb_sv39x4 import ariane_pkg::*; @@ -27,6 +28,7 @@ module cva6_tlb_sv39x4 ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low + input logic clear_i, input logic flush_i, // Flush normal translations signal input logic flush_vvma_i, // Flush vs stage signal input logic flush_gvma_i, // Flush g stage signal @@ -357,17 +359,10 @@ module cva6_tlb_sv39x4 end // sequential process - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - tags_q <= '{default: 0}; - content_q <= '{default: 0}; - plru_tree_q <= '{default: 0}; - end else begin - tags_q <= tags_n; - content_q <= content_n; - plru_tree_q <= plru_tree_n; - end - end + `FFARNC(tags_q, tags_n, clear_i, '{default: 0}, clk_i, rst_ni) + `FFARNC(content_q, content_n, clear_i, '{default: 0}, clk_i, rst_ni) + `FFARNC(plru_tree_q, plru_tree_n, clear_i, '{default: 0}, clk_i, rst_ni) + //-------------- // Sanity checks //-------------- diff --git a/core/mult.sv b/core/mult.sv index dcb0fa6a3c..bb86ab70e8 100644 --- a/core/mult.sv +++ b/core/mult.sv @@ -1,4 +1,4 @@ - +`include "common_cells/registers.svh" module mult import ariane_pkg::*; @@ -9,6 +9,8 @@ module mult input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // Flush - CONTROLLER input logic flush_i, // FU data needed to execute instruction - ISSUE_STAGE @@ -59,6 +61,7 @@ module mult ) i_multiplier ( .clk_i, .rst_ni, + .clear_i, .trans_id_i (fu_data_i.trans_id), .operation_i (fu_data_i.operation), .operand_a_i (fu_data_i.operand_a), @@ -128,6 +131,7 @@ module mult ) i_div ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .id_i (fu_data_i.trans_id), .op_a_i (operand_a), .op_b_i (operand_b), @@ -148,11 +152,6 @@ module mult // --------------------- // Registers // --------------------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - word_op_q <= '0; - end else begin - word_op_q <= word_op_d; - end - end + `FFARNC(word_op_q, word_op_d, clear_i, '0, clk_i, rst_ni) + endmodule diff --git a/core/multiplier.sv b/core/multiplier.sv index bdcd36e884..339f0a1ee7 100644 --- a/core/multiplier.sv +++ b/core/multiplier.sv @@ -14,6 +14,7 @@ // This unit relies on retiming features of the synthesizer // +`include "common_cells/registers.svh" module multiplier import ariane_pkg::*; @@ -24,6 +25,8 @@ module multiplier input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high + input logic clear_i, // Multiplier transaction ID - Mult input logic [TRANS_ID_BITS-1:0] trans_id_i, // Multiplier instruction is valid - Mult @@ -138,32 +141,14 @@ module multiplier endcase end if (CVA6Cfg.RVB) begin - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - clmul_q <= '0; - clmulr_q <= '0; - end else begin - clmul_q <= clmul_d; - clmulr_q <= clmulr_d; - end - end + `FFARNC(clmul_q, clmul_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(clmulr_q, clmulr_d, clear_i, '0, clk_i, rst_ni) end // ----------------------- // Output pipeline register // ----------------------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - mult_valid_q <= '0; - trans_id_q <= '0; - operator_q <= MUL; - mult_result_q <= '0; - end else begin - // Input silencing - trans_id_q <= trans_id_i; - // Output Register - mult_valid_q <= mult_valid; - operator_q <= operator_d; - mult_result_q <= mult_result_d; - end - end + `FFARNC(mult_valid_q, mult_valid, clear_i, '0, clk_i, rst_ni) + `FFARNC(trans_id_q, trans_id_i, clear_i, '0, clk_i, rst_ni) + `FFARNC(operator_q, operator_d, clear_i, MUL, clk_i, rst_ni) + `FFARNC(mult_result_q, mult_result_d, clear_i, '0, clk_i, rst_ni) endmodule diff --git a/core/perf_counters.sv b/core/perf_counters.sv index e78eebe22b..a9fc5c539a 100644 --- a/core/perf_counters.sv +++ b/core/perf_counters.sv @@ -12,6 +12,7 @@ // Date: 06.10.2017 // Description: Performance counters +`include "common_cells/registers.svh" module perf_counters import ariane_pkg::*; @@ -21,6 +22,7 @@ module perf_counters ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, input logic debug_mode_i, // debug mode // SRAM like interface input logic [11:0] addr_i, // read/write address (up to 6 counters possible) @@ -232,14 +234,7 @@ module perf_counters end //Registers - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - generic_counter_q <= '{default: 0}; - mhpmevent_q <= '{default: 0}; - end else begin - generic_counter_q <= generic_counter_d; - mhpmevent_q <= mhpmevent_d; - end - end + `FFARNC(generic_counter_q, generic_counter_d, clear_i, '{default: 0}, clk_i, rst_ni) + `FFARNC(mhpmevent_q, mhpmevent_d, clear_i, '{default: 0}, clk_i, rst_ni) endmodule diff --git a/core/scoreboard.sv b/core/scoreboard.sv index 568a4aa7ef..0bfe87ae7f 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -12,6 +12,8 @@ // Date: 08.04.2017 // Description: Scoreboard - keeps track of all decoded, issued and committed instructions +`include "common_cells/registers.svh" + module scoreboard #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type rs3_len_t = logic @@ -20,6 +22,8 @@ module scoreboard #( input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // TO_BE_COMPLETED - TO_BE_COMPLETED output logic sb_full_o, // Flush only un-issued instructions - TO_BE_COMPLETED @@ -283,7 +287,7 @@ module scoreboard #( ) i_sel_gpr_clobbers ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i(1'b0), + .flush_i(clear_i), .rr_i ('0), .req_i (gpr_clobber_vld[k]), .gnt_o (), @@ -302,7 +306,7 @@ module scoreboard #( ) i_sel_fpr_clobbers ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i(1'b0), + .flush_i(clear_i), .rr_i ('0), .req_i (fpr_clobber_vld[k]), .gnt_o (), @@ -370,7 +374,7 @@ module scoreboard #( ) i_sel_rs1 ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i(1'b0), + .flush_i(clear_i), .rr_i ('0), .req_i (rs1_fwd_req), .gnt_o (), @@ -389,7 +393,7 @@ module scoreboard #( ) i_sel_rs2 ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i(1'b0), + .flush_i(clear_i), .rr_i ('0), .req_i (rs2_fwd_req), .gnt_o (), @@ -410,7 +414,7 @@ module scoreboard #( ) i_sel_rs3 ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i(1'b0), + .flush_i(clear_i), .rr_i ('0), .req_i (rs3_fwd_req), .gnt_o (), @@ -429,19 +433,10 @@ module scoreboard #( // sequential process - always_ff @(posedge clk_i or negedge rst_ni) begin : regs - if (!rst_ni) begin - mem_q <= '{default: sb_mem_t'(0)}; - issue_cnt_q <= '0; - commit_pointer_q <= '0; - issue_pointer_q <= '0; - end else begin - issue_cnt_q <= issue_cnt_n; - issue_pointer_q <= issue_pointer_n; - mem_q <= mem_n; - commit_pointer_q <= commit_pointer_n; - end - end + `FFARNC(issue_cnt_q, issue_cnt_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(issue_pointer_q, issue_pointer_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(mem_q, mem_n, clear_i, '{default: sb_mem_t'(0)}, clk_i, rst_ni) + `FFARNC(commit_pointer_q, commit_pointer_n, clear_i, '0, clk_i, rst_ni) //RVFI assign rvfi_issue_pointer_o = issue_pointer_q; diff --git a/core/serdiv.sv b/core/serdiv.sv index 328cfc7205..2280e84d09 100644 --- a/core/serdiv.sv +++ b/core/serdiv.sv @@ -14,6 +14,7 @@ // Date: 18.10.2018 // Description: simple 64bit serial divider +`include "common_cells/registers.svh" module serdiv import ariane_pkg::*; @@ -26,6 +27,8 @@ module serdiv input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // Serdiv translation ID - Mult input logic [TRANS_ID_BITS-1:0] id_i, // A operand - Mult @@ -246,34 +249,17 @@ module serdiv assign op_b_d = (b_reg_en) ? b_mux : op_b_q; assign res_d = (load_en) ? '0 : (res_reg_en) ? {res_q[$high(res_q)-1:0], ab_comp} : res_q; - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (~rst_ni) begin - state_q <= IDLE; - op_a_q <= '0; - op_b_q <= '0; - res_q <= '0; - cnt_q <= '0; - id_q <= '0; - rem_sel_q <= 1'b0; - comp_inv_q <= 1'b0; - res_inv_q <= 1'b0; - op_b_zero_q <= 1'b0; - op_b_neg_one_q <= 1'b0; - div_res_zero_q <= 1'b0; - end else begin - state_q <= state_d; - op_a_q <= op_a_d; - op_b_q <= op_b_d; - res_q <= res_d; - cnt_q <= cnt_d; - id_q <= id_d; - rem_sel_q <= rem_sel_d; - comp_inv_q <= comp_inv_d; - res_inv_q <= res_inv_d; - op_b_zero_q <= op_b_zero_d; - op_b_neg_one_q <= op_b_neg_one_d; - div_res_zero_q <= div_res_zero_d; - end - end + `FFARNC(state_q, state_d, clear_i, IDLE, clk_i, rst_ni) + `FFARNC(op_a_q, op_a_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(op_b_q, op_b_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(res_q, res_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(cnt_q, cnt_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(id_q, id_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(rem_sel_q, rem_sel_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(comp_inv_q, comp_inv_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(res_inv_q, res_inv_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(op_b_zero_q, op_b_zero_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(op_b_neg_one_q, op_b_neg_one_d, clear_i, '0, clk_i, rst_ni) + `FFARNC(div_res_zero_q, div_res_zero_d, clear_i, '0, clk_i, rst_ni) endmodule diff --git a/core/store_buffer.sv b/core/store_buffer.sv index d41551d555..8e82d385d4 100644 --- a/core/store_buffer.sv +++ b/core/store_buffer.sv @@ -13,6 +13,7 @@ // Description: Store queue persists store requests and pushes them to memory // if they are no longer speculative +`include "common_cells/registers.svh" module store_buffer import ariane_pkg::*; @@ -21,6 +22,7 @@ module store_buffer ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low + input logic clear_i, input logic flush_i, // if we flush we need to pause the transactions on the memory // otherwise we will run in a deadlock with the memory arbiter input logic stall_st_pending_i, // Stall issuing non-speculative request @@ -232,34 +234,15 @@ module store_buffer // registers - always_ff @(posedge clk_i or negedge rst_ni) begin : p_spec - if (~rst_ni) begin - speculative_queue_q <= '{default: 0}; - speculative_read_pointer_q <= '0; - speculative_write_pointer_q <= '0; - speculative_status_cnt_q <= '0; - end else begin - speculative_queue_q <= speculative_queue_n; - speculative_read_pointer_q <= speculative_read_pointer_n; - speculative_write_pointer_q <= speculative_write_pointer_n; - speculative_status_cnt_q <= speculative_status_cnt_n; - end - end - - // registers - always_ff @(posedge clk_i or negedge rst_ni) begin : p_commit - if (~rst_ni) begin - commit_queue_q <= '{default: 0}; - commit_read_pointer_q <= '0; - commit_write_pointer_q <= '0; - commit_status_cnt_q <= '0; - end else begin - commit_queue_q <= commit_queue_n; - commit_read_pointer_q <= commit_read_pointer_n; - commit_write_pointer_q <= commit_write_pointer_n; - commit_status_cnt_q <= commit_status_cnt_n; - end - end + `FFARNC(speculative_queue_q, speculative_queue_n, clear_i, '{default: 0}, clk_i, rst_ni) + `FFARNC(speculative_read_pointer_q, speculative_read_pointer_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(speculative_write_pointer_q, speculative_write_pointer_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(speculative_status_cnt_q, speculative_status_cnt_n, clear_i, '0, clk_i, rst_ni) + + `FFARNC(commit_queue_q, commit_queue_n, clear_i, '{default: 0}, clk_i, rst_ni) + `FFARNC(commit_read_pointer_q, commit_read_pointer_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(commit_write_pointer_q, commit_write_pointer_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(commit_status_cnt_q, commit_status_cnt_n, clear_i, '0, clk_i, rst_ni) /////////////////////////////////////////////////////// // assertions diff --git a/core/store_unit.sv b/core/store_unit.sv index 315f542973..fe4e98e244 100644 --- a/core/store_unit.sv +++ b/core/store_unit.sv @@ -12,6 +12,7 @@ // Date: 22.05.2017 // Description: Store Unit, takes care of all store requests and atomic memory operations (AMOs) +`include "common_cells/registers.svh" module store_unit import ariane_pkg::*; @@ -22,6 +23,8 @@ module store_unit input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, + // Synchronous clear active high - SUBSYSTEM + input logic clear_i, // Flush - CONTROLLER input logic flush_i, // TO_BE_COMPLETED - TO_BE_COMPLETED @@ -257,6 +260,7 @@ module store_unit ) store_buffer_i ( .clk_i, .rst_ni, + .clear_i, .flush_i, .stall_st_pending_i, .no_st_pending_o, @@ -308,22 +312,11 @@ module store_unit // --------------- // Registers // --------------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - state_q <= IDLE; - st_be_q <= '0; - st_data_q <= '0; - st_data_size_q <= '0; - trans_id_q <= '0; - amo_op_q <= AMO_NONE; - end else begin - state_q <= state_d; - st_be_q <= st_be_n; - st_data_q <= st_data_n; - trans_id_q <= trans_id_n; - st_data_size_q <= st_data_size_n; - amo_op_q <= amo_op_d; - end - end + `FFARNC(state_q, state_d, clear_i, IDLE, clk_i, rst_ni) + `FFARNC(st_be_q, st_be_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(st_data_q, st_data_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(trans_id_q, trans_id_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(st_data_size_q, st_data_size_n, clear_i, '0, clk_i, rst_ni) + `FFARNC(amo_op_q, amo_op_d, clear_i, AMO_NONE, clk_i, rst_ni) endmodule diff --git a/corev_apu/src/ariane.sv b/corev_apu/src/ariane.sv index a0690e8181..b6d4fedb2b 100644 --- a/corev_apu/src/ariane.sv +++ b/corev_apu/src/ariane.sv @@ -61,6 +61,7 @@ module ariane import ariane_pkg::*; #( ) i_cva6 ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), + .clear_i ( '0 ), .boot_addr_i ( boot_addr_i ), .hart_id_i ( hart_id_i ), .irq_i ( irq_i ), diff --git a/vendor/pulp-platform/common_cells/include/common_cells/registers.svh b/vendor/pulp-platform/common_cells/include/common_cells/registers.svh index b64f31a013..b4d532da0c 100644 --- a/vendor/pulp-platform/common_cells/include/common_cells/registers.svh +++ b/vendor/pulp-platform/common_cells/include/common_cells/registers.svh @@ -208,6 +208,29 @@ end \ end +// Flip-Flop with asynchronous active-low reset and synchronous clear +// __q: Q output of FF +// __d: D input of FF +// __clear: assign reset value into FF +// __reset_value: value assigned upon reset +// __clk: clock input +// __arst_n: asynchronous reset, active-low +`define FFARNC(__q, __d, __clear, __reset_value, __clk, __arst_n) \ + `ifndef NO_SYNOPSYS_FF \ + /``* synopsys sync_set_reset `"__clear`" *``/ \ + `endif \ + always_ff @(posedge (__clk) or negedge (__arst_n)) begin \ + if (!__arst_n) begin \ + __q <= (__reset_value); \ + end else begin \ + if (__clear) begin \ + __q <= (__reset_value); \ + end begin \ + __q <= (__d); \ + end \ + end \ + end + // Load-enable Flip-Flop without reset // __q: Q output of FF // __d: D input of FF