Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hw: Replace non-resettable FFs #154

Merged
merged 6 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading