Skip to content

Commit

Permalink
hw: Replace non-resettable FFs (#154)
Browse files Browse the repository at this point in the history
Co-authored-by: Milos Hirsl <[email protected]>
Co-authored-by: Thierry Dubochet <[email protected]>
  • Loading branch information
3 people authored Jul 23, 2024
1 parent 4418183 commit c12ce9b
Show file tree
Hide file tree
Showing 17 changed files with 176 additions and 180 deletions.
12 changes: 6 additions & 6 deletions hw/reqrsp_interface/src/axi_to_reqrsp.sv
Original file line number Diff line number Diff line change
Expand Up @@ -371,12 +371,12 @@ module axi_to_reqrsp #(
};

// Registers
`FFARN(meta_sel_q, meta_sel_d, 1'b0, clk_i, rst_ni)
`FFARN(sel_lock_q, sel_lock_d, 1'b0, clk_i, rst_ni)
`FFARN(rd_meta_q, rd_meta_d, meta_t'{default: '0}, clk_i, rst_ni)
`FFARN(wr_meta_q, wr_meta_d, meta_t'{default: '0}, clk_i, rst_ni)
`FFARN(r_cnt_q, r_cnt_d, '0, clk_i, rst_ni)
`FFARN(w_cnt_q, w_cnt_d, '0, clk_i, rst_ni)
`FF(meta_sel_q, meta_sel_d, 1'b0, clk_i, rst_ni)
`FF(sel_lock_q, sel_lock_d, 1'b0, clk_i, rst_ni)
`FF(rd_meta_q, rd_meta_d, meta_t'{default: '0}, clk_i, rst_ni)
`FF(wr_meta_q, wr_meta_d, meta_t'{default: '0}, clk_i, rst_ni)
`FF(r_cnt_q, r_cnt_d, '0, clk_i, rst_ni)
`FF(w_cnt_q, w_cnt_d, '0, clk_i, rst_ni)

// Assertions
// Make sure that write is never set for AMOs.
Expand Down
23 changes: 12 additions & 11 deletions hw/snitch/src/snitch.sv
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,10 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #(
logic [31:0] dscratch_d, dscratch_q;
logic debug_d, debug_q;

`FFNR(scratch_q, scratch_d, clk_i)
`FFNR(tvec_q, tvec_d, clk_i)
`FFNR(epc_q, epc_d, clk_i)
`FFNR(satp_q, satp_d, clk_i)
`FFAR(scratch_q, scratch_d, '0, clk_i, rst_i)
`FFAR(tvec_q, tvec_d, '0, clk_i, rst_i)
`FFAR(epc_q, epc_d, '0, clk_i, rst_i)
`FFAR(satp_q, satp_d, '0, clk_i, rst_i)
`FFAR(cause_q, cause_d, '0, clk_i, rst_i)
`FFAR(cause_irq_q, cause_irq_d, '0, clk_i, rst_i)
`FFAR(priv_lvl_q, priv_lvl_d, snitch_pkg::PrivLvlM, clk_i, rst_i)
Expand All @@ -305,8 +305,8 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #(

if (DebugSupport) begin : gen_debug
`FFAR(dcsr_q, dcsr_d, '0, clk_i, rst_i)
`FFNR(dpc_q, dpc_d, clk_i)
`FFNR(dscratch_q, dscratch_d, clk_i)
`FFAR(dpc_q, dpc_d, '0, clk_i, rst_i)
`FFAR(dscratch_q, dscratch_d, '0, clk_i, rst_i)
`FFAR(debug_q, debug_d, '0, clk_i, rst_i) // Debug mode
end else begin : gen_no_debug
assign dcsr_q = '0;
Expand Down Expand Up @@ -2623,13 +2623,14 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #(
// pragma translate_on

snitch_regfile #(
.DATA_WIDTH ( 32 ),
.NR_READ_PORTS ( 2 ),
.NR_WRITE_PORTS ( 1 ),
.ZERO_REG_ZERO ( 1 ),
.ADDR_WIDTH ( RegWidth )
.DataWidth ( 32 ),
.NrReadPorts ( 2 ),
.NrWritePorts ( 1 ),
.ZeroRegZero ( 1 ),
.AddrWidth ( RegWidth )
) i_snitch_regfile (
.clk_i,
.rst_ni ( ~rst_i ),
.raddr_i ( gpr_raddr ),
.rdata_o ( gpr_rdata ),
.waddr_i ( gpr_waddr ),
Expand Down
7 changes: 4 additions & 3 deletions hw/snitch/src/snitch_l0_tlb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51

`include "common_cells/registers.svh"
// Author: Florian Zaruba <[email protected]>

`include "common_cells/registers.svh"

// MMU w/ L0 TLB
module snitch_l0_tlb import snitch_pkg::*; #(
parameter int unsigned NrEntries = 1,
Expand Down Expand Up @@ -66,8 +67,8 @@ module snitch_l0_tlb import snitch_pkg::*; #(
l0_pte_t pte;

`FFAR(tag_valid_q, tag_valid_d, '0, clk_i, rst_i)
`FFNR(tag_q, tag_d, clk_i)
`FFNR(pte_q, pte_d, clk_i)
`FFAR(tag_q, tag_d, '0, clk_i, rst_i)
`FFAR(pte_q, pte_d, '0, clk_i, rst_i)

logic [NrEntries-1:0] hit;
logic miss_d, miss_q; // we got a miss
Expand Down
59 changes: 32 additions & 27 deletions hw/snitch/src/snitch_regfile_ff.sv
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,58 @@
// Description: Variable Register File
// verilog_lint: waive module-filename
module snitch_regfile #(
parameter int unsigned DATA_WIDTH = 32,
parameter int unsigned NR_READ_PORTS = 2,
parameter int unsigned NR_WRITE_PORTS = 1,
parameter bit ZERO_REG_ZERO = 0,
parameter int unsigned ADDR_WIDTH = 4
parameter int unsigned DataWidth = 32,
parameter int unsigned NrReadPorts = 2,
parameter int unsigned NrWritePorts = 1,
parameter bit ZeroRegZero = 0,
parameter int unsigned AddrWidth = 4
) (
// clock and reset
input logic clk_i,
input logic clk_i,
input logic rst_ni,
// read port
input logic [NR_READ_PORTS-1:0][ADDR_WIDTH-1:0] raddr_i,
output logic [NR_READ_PORTS-1:0][DATA_WIDTH-1:0] rdata_o,
input logic [NrReadPorts-1:0][AddrWidth-1:0] raddr_i,
output logic [NrReadPorts-1:0][DataWidth-1:0] rdata_o,
// write port
input logic [NR_WRITE_PORTS-1:0][ADDR_WIDTH-1:0] waddr_i,
input logic [NR_WRITE_PORTS-1:0][DATA_WIDTH-1:0] wdata_i,
input logic [NR_WRITE_PORTS-1:0] we_i
input logic [NrWritePorts-1:0][AddrWidth-1:0] waddr_i,
input logic [NrWritePorts-1:0][DataWidth-1:0] wdata_i,
input logic [NrWritePorts-1:0] we_i
);

localparam int unsigned NumWords = 2**ADDR_WIDTH;
localparam int unsigned NumWords = 2**AddrWidth;

logic [NumWords-1:0][DATA_WIDTH-1:0] mem;
logic [NR_WRITE_PORTS-1:0][NumWords-1:0] we_dec;
logic [NumWords-1:0][DataWidth-1:0] mem;
logic [NrWritePorts-1:0][NumWords-1:0] we_dec;


always_comb begin : we_decoder
for (int unsigned j = 0; j < NR_WRITE_PORTS; j++) begin
for (int unsigned i = 0; i < NumWords; i++) begin
if (waddr_i[j] == i) we_dec[j][i] = we_i[j];
else we_dec[j][i] = 1'b0;
end
always_comb begin : we_decoder
for (int unsigned j = 0; j < NrWritePorts; j++) begin
for (int unsigned i = 0; i < NumWords; i++) begin
if (waddr_i[j] == i) we_dec[j][i] = we_i[j];
else we_dec[j][i] = 1'b0;
end
end
end

// loop from 1 to NumWords-1 as R0 is nil
always_ff @(posedge clk_i) begin : register_write_behavioral
for (int unsigned j = 0; j < NR_WRITE_PORTS; j++) begin
// loop from 1 to NumWords-1 as R0 is nil
always_ff @(posedge clk_i, negedge rst_ni) begin : register_write_behavioral
if (~rst_ni) begin
mem <= '0;
end else begin
for (int unsigned j = 0; j < NrWritePorts; j++) begin
for (int unsigned i = 0; i < NumWords; 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 (ZeroRegZero) begin
mem[0] <= '0;
end
end
end

for (genvar i = 0; i < NR_READ_PORTS; i++) begin : gen_read_port
for (genvar i = 0; i < NrReadPorts; i++) begin : gen_read_port
assign rdata_o[i] = mem[raddr_i[i]];
end

Expand Down
57 changes: 26 additions & 31 deletions hw/snitch/src/snitch_regfile_fpga.sv
Original file line number Diff line number Diff line change
Expand Up @@ -22,41 +22,42 @@

// verilog_lint: waive module-filename
module snitch_regfile #(
parameter int unsigned DATA_WIDTH = 32,
parameter int unsigned NR_READ_PORTS = 2,
parameter int unsigned NR_WRITE_PORTS = 1,
parameter bit ZERO_REG_ZERO = 0,
parameter int unsigned ADDR_WIDTH = 4
parameter int unsigned DataWidth = 32,
parameter int unsigned NrReadPorts = 2,
parameter int unsigned NrWritePorts = 1,
parameter bit ZeroRegZero = 0,
parameter int unsigned AddrWidth = 4
)(
// clock and reset
input logic clk_i,
input logic clk_i,
input logic rst_ni,
// read port
input logic [NR_READ_PORTS-1:0][4:0] raddr_i,
output logic [NR_READ_PORTS-1:0][DATA_WIDTH-1:0] rdata_o,
input logic [NrReadPorts-1:0][4:0] raddr_i,
output logic [NrReadPorts-1:0][DataWidth-1:0] rdata_o,
// write port
input logic [NR_WRITE_PORTS-1:0][4:0] waddr_i,
input logic [NR_WRITE_PORTS-1:0][DATA_WIDTH-1:0] wdata_i,
input logic [NR_WRITE_PORTS-1:0] we_i
input logic [NrWritePorts-1:0][4:0] waddr_i,
input logic [NrWritePorts-1:0][DataWidth-1:0] wdata_i,
input logic [NrWritePorts-1:0] we_i
);

localparam int unsigned NumWords = 2**ADDR_WIDTH;
localparam int unsigned LogNrWritePorts = NR_WRITE_PORTS == 1 ? 1 : $clog2(NR_WRITE_PORTS);
localparam int unsigned NumWords = 2**AddrWidth;
localparam int unsigned LogNrWritePorts = NrWritePorts == 1 ? 1 : $clog2(NrWritePorts);

// The register values are stored in distinct separate RAM blocks each featuring 1 sync-write and
// N async-read ports. A set of narrow flip-flops keeps track of which RAM block contains the
// valid entry for each register.

// Distributed RAM usually supports one write port per block. We need one block per write port.
logic [NumWords-1:0][DATA_WIDTH-1:0] mem [NR_WRITE_PORTS];
logic [NumWords-1:0][DataWidth-1:0] mem [NrWritePorts];


logic [NR_WRITE_PORTS-1:0][NumWords-1:0] we_dec;
logic [NrWritePorts-1:0][NumWords-1:0] we_dec;
logic [NumWords-1:0][LogNrWritePorts-1:0] mem_block_sel;
logic [NumWords-1:0][LogNrWritePorts-1:0] mem_block_sel_q;

// write adress decoder (for block selector)
always_comb begin
for (int unsigned j = 0; j < NR_WRITE_PORTS; j++) begin
for (int unsigned j = 0; j < NrWritePorts; j++) begin
for (int unsigned i = 0; i < NumWords; i++) begin
if (waddr_i[j] == i) begin
we_dec[j][i] = we_i[j];
Expand All @@ -74,7 +75,7 @@ module snitch_regfile #(
always_comb begin
mem_block_sel = mem_block_sel_q;
for (int i = 0; i<NumWords; i++) begin
for (int j = 0; j<NR_WRITE_PORTS; j++) begin
for (int j = 0; j<NrWritePorts; j++) begin
if (we_dec[j][i] == 1'b1) begin
mem_block_sel[i] = LogNrWritePorts'(j);
end
Expand All @@ -83,29 +84,23 @@ module snitch_regfile #(
end

// block selector flops
always_ff @(posedge clk_i) begin
mem_block_sel_q <= mem_block_sel;
end
`FF(mem_block_sel_q, mem_block_sel, '0, clk_i, rst_ni)

// distributed RAM blocks
logic [NR_READ_PORTS-1:0] [DATA_WIDTH-1:0] mem_read [NR_WRITE_PORTS];
for (genvar j=0; j<NR_WRITE_PORTS; j++) begin : gen_regfile_ram_block
always_ff @(posedge clk_i) begin
if (we_i[j]) begin
mem[j][waddr_i[j]] <= wdata_i[j];
end
end
for (genvar k=0; k<NR_READ_PORTS; k++) begin : gen_block_read
logic [NrReadPorts-1:0] [DataWidth-1:0] mem_read [NrWritePorts];
for (genvar j=0; j<NrWritePorts; j++) begin : gen_regfile_ram_block
`FFL(mem[j][waddr_i[j]], wdata_i[j], we_i[j], '0, clk_i, rst_ni)
for (genvar k=0; k<NrReadPorts; k++) begin : gen_block_read
assign mem_read[j][k] = mem[j][raddr_i[k]];
end
end

// output MUX
logic [NR_READ_PORTS-1:0][LogNrWritePorts-1:0] block_addr;
for (genvar k = 0; k < NR_READ_PORTS; k++) begin : gen_regfile_read_port
logic [NrReadPorts-1:0][LogNrWritePorts-1:0] block_addr;
for (genvar k = 0; k < NrReadPorts; k++) begin : gen_regfile_read_port
assign block_addr[k] = mem_block_sel_q[raddr_i[k]];
assign rdata_o[k] =
(ZERO_REG_ZERO && raddr_i[k] == '0 ) ? '0 : mem_read[block_addr[k]][k];
(ZeroRegZero && raddr_i[k] == '0 ) ? '0 : mem_read[block_addr[k]][k];
end

endmodule
50 changes: 26 additions & 24 deletions hw/snitch/src/snitch_regfile_latch.sv
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,36 @@
// Description: Variable Register File
// verilog_lint: waive module-filename
module snitch_regfile #(
parameter int unsigned DATA_WIDTH = 32,
parameter int unsigned NR_READ_PORTS = 2,
parameter int unsigned NR_WRITE_PORTS = 1,
parameter bit ZERO_REG_ZERO = 1,
parameter int unsigned ADDR_WIDTH = 4
parameter int unsigned DataWidth = 32,
parameter int unsigned NrReadPorts = 2,
parameter int unsigned NrWritePorts = 1,
parameter bit ZeroRegZero = 1,
parameter int unsigned AddrWidth = 4
) (
// clock and reset
input logic clk_i,
input logic clk_i,
input logic rst_ni,
// read port
input logic [NR_READ_PORTS-1:0][ADDR_WIDTH-1:0] raddr_i,
output logic [NR_READ_PORTS-1:0][DATA_WIDTH-1:0] rdata_o,
input logic [NrReadPorts-1:0][AddrWidth-1:0] raddr_i,
output logic [NrReadPorts-1:0][DataWidth-1:0] rdata_o,
// write port
input logic [NR_WRITE_PORTS-1:0][ADDR_WIDTH-1:0] waddr_i,
input logic [NR_WRITE_PORTS-1:0][DATA_WIDTH-1:0] wdata_i,
input logic [NR_WRITE_PORTS-1:0] we_i
input logic [NrWritePorts-1:0][AddrWidth-1:0] waddr_i,
input logic [NrWritePorts-1:0][DataWidth-1:0] wdata_i,
input logic [NrWritePorts-1:0] we_i
);

localparam int unsigned NumWords = 2**ADDR_WIDTH;
localparam int unsigned NumWords = 2**AddrWidth;

logic clk;
logic [NumWords-1:0] mem_clocks;

logic [NumWords-1:0][DATA_WIDTH-1:0] mem;
logic [NumWords-1:0][DataWidth-1:0] mem;

logic [NR_WRITE_PORTS-1:0][DATA_WIDTH-1:0] wdata_q;
logic [NR_WRITE_PORTS-1:0][NumWords-1:0] waddr_onehot;
logic [NumWords-1:0][NR_WRITE_PORTS-1:0] waddr_onehot_trans; // transposed index version
logic [NrWritePorts-1:0][DataWidth-1:0] wdata_q;
logic [NrWritePorts-1:0][NumWords-1:0] waddr_onehot;
logic [NumWords-1:0][NrWritePorts-1:0] waddr_onehot_trans; // transposed index version

for (genvar i = 0; i < NR_WRITE_PORTS; i++) begin : gen_oh_write_ports
for (genvar i = 0; i < NrWritePorts; i++) begin : gen_oh_write_ports
for (genvar j = 0; j < NumWords; j++) begin : gen_oh_words
assign waddr_onehot_trans[j][i] = waddr_onehot[i][j];
end
Expand All @@ -48,10 +49,11 @@ module snitch_regfile #(
);

// Sample Input Data
for (genvar i = 0; i < NR_WRITE_PORTS; i++) begin : gen_data_ports
always_ff @(posedge clk) wdata_q[i] <= wdata_i[i];
for (genvar i = 0; i < NrWritePorts; i++) begin : gen_data_ports

for (genvar j = ZERO_REG_ZERO; j < NumWords; j++) begin : gen_data_words
`FF(wdata_q[i], wdata_i[i], '0, clk, rst_ni)

for (genvar j = ZeroRegZero; j < NumWords; j++) begin : gen_data_words
always_comb begin
if (we_i[i] && waddr_i[i] == j) waddr_onehot[i][j] = 1'b1;
else waddr_onehot[i][j] = 1'b0;
Expand All @@ -69,10 +71,10 @@ module snitch_regfile #(
end

always_latch begin
if (ZERO_REG_ZERO) mem[0] = '0;
if (ZeroRegZero) mem[0] = '0;

for (int unsigned i = ZERO_REG_ZERO; i < NumWords; i++) begin : gen_read_words
for (int unsigned j = 0; j < NR_WRITE_PORTS; j++) begin : gen_read_ports
for (int unsigned i = ZeroRegZero; i < NumWords; i++) begin : gen_read_words
for (int unsigned j = 0; j < NrWritePorts; j++) begin : gen_read_ports
if (mem_clocks[i]) begin
// TODO(zarubaf) generalize to more than 1 read port
mem[i] = wdata_q[j];
Expand All @@ -81,6 +83,6 @@ module snitch_regfile #(
end
end

for (genvar i = 0; i < NR_READ_PORTS; i++) assign rdata_o[i] = mem[raddr_i[i][ADDR_WIDTH-1:0]];
for (genvar i = 0; i < NrReadPorts; i++) assign rdata_o[i] = mem[raddr_i[i][AddrWidth-1:0]];

endmodule
10 changes: 5 additions & 5 deletions hw/snitch_cluster/src/snitch_amo_shim.sv
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,12 @@ module snitch_amo_shim
assign wdata = $unsigned(wdata_i);

`FF(state_q, state_d, Idle)
`FFLNR(amo_op_q, amo_i, load_amo, clk_i)
`FFLNR(addr_q, addr_i, load_amo, clk_i)
`FFL(amo_op_q, amo_i, load_amo, AMONone, clk_i, rst_ni)
`FFL(addr_q, addr_i, load_amo, '0, clk_i, rst_ni)
// Which word to pick.
`FFLNR(idx_q, idx_d, load_amo, clk_i)
`FFLNR(operand_b_q, (wstrb_i[0] ? wdata[31:0] : wdata[63:32]), load_amo, clk_i)
`FFLNR(amo_result_q, amo_result, (state_q == DoAMO), clk_i)
`FFL(idx_q, idx_d, load_amo, '0, clk_i, rst_ni)
`FFL(operand_b_q, (wstrb_i[0] ? wdata[31:0] : wdata[63:32]), load_amo, '0, clk_i, rst_ni)
`FFL(amo_result_q, amo_result, (state_q == DoAMO), '0, clk_i, rst_ni)

assign idx_d = ((DataWidth == 64) ? wstrb_i[DataWidth/8/2] : 0);
assign load_amo = valid_i & ready_o &
Expand Down
Loading

0 comments on commit c12ce9b

Please sign in to comment.