mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-19 03:44:46 -04:00
Optimize FPGA memories (#989)
This commit is contained in:
parent
ec61b89df6
commit
c5947082c4
14 changed files with 796 additions and 31 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,9 +1,6 @@
|
|||
[submodule "corev_apu/axi_mem_if"]
|
||||
path = corev_apu/axi_mem_if
|
||||
url = https://github.com/pulp-platform/axi_mem_if.git
|
||||
[submodule "corev_apu/fpga-support"]
|
||||
path = corev_apu/fpga-support
|
||||
url = https://github.com/pulp-platform/fpga-support.git
|
||||
[submodule "common/submodules/common_cells"]
|
||||
path = common/submodules/common_cells
|
||||
url = https://github.com/pulp-platform/common_cells.git
|
||||
|
|
|
@ -163,7 +163,7 @@ sources:
|
|||
- corev_apu/axi/src/axi_mux.sv
|
||||
- corev_apu/axi/src/axi_demux.sv
|
||||
- corev_apu/axi/src/axi_xbar.sv
|
||||
- corev_apu/fpga-support/rtl/SyncSpRamBeNx64.sv
|
||||
- common/local/techlib/fpga/rtl/SyncSpRamBeNx64.sv
|
||||
- common/submodules/common_cells/src/sync.sv
|
||||
- common/submodules/common_cells/src/popcount.sv
|
||||
- common/submodules/common_cells/src/unread.sv
|
||||
|
|
3
Makefile
3
Makefile
|
@ -203,6 +203,7 @@ src := $(filter-out core/ariane_regfile.sv, $(wildcard core/*.sv))
|
|||
corev_apu/axi/src/axi_mux.sv \
|
||||
corev_apu/axi/src/axi_demux.sv \
|
||||
corev_apu/axi/src/axi_xbar.sv \
|
||||
common/local/techlib/fpga/rtl/SyncSpRamBeNx64.sv \
|
||||
common/submodules/common_cells/src/unread.sv \
|
||||
common/submodules/common_cells/src/sync.sv \
|
||||
common/submodules/common_cells/src/cdc_2phase.sv \
|
||||
|
@ -254,7 +255,7 @@ copro_src := $(addprefix $(root-dir), $(copro_src))
|
|||
uart_src := $(wildcard corev_apu/fpga/src/apb_uart/src/*.vhd)
|
||||
uart_src := $(addprefix $(root-dir), $(uart_src))
|
||||
|
||||
fpga_src := $(wildcard corev_apu/fpga/src/*.sv) $(wildcard corev_apu/fpga/src/bootrom/*.sv) $(wildcard corev_apu/fpga/src/ariane-ethernet/*.sv) corev_apu/src/tech_cells_generic/src/fpga/tc_sram_xilinx.sv common/local/util/tc_sram_xilinx_wrapper.sv
|
||||
fpga_src := $(wildcard corev_apu/fpga/src/*.sv) $(wildcard corev_apu/fpga/src/bootrom/*.sv) $(wildcard corev_apu/fpga/src/ariane-ethernet/*.sv) common/local/util/tc_sram_fpga_wrapper.sv
|
||||
fpga_src := $(addprefix $(root-dir), $(fpga_src))
|
||||
|
||||
# look for testbenches
|
||||
|
|
182
common/local/techlib/fpga/rtl/SyncDpRam.sv
Normal file
182
common/local/techlib/fpga/rtl/SyncDpRam.sv
Normal file
|
@ -0,0 +1,182 @@
|
|||
// Copyright 2014 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
/**
|
||||
* Inferable, Synchronous Dual-Port RAM
|
||||
*
|
||||
* This module is designed to work with both Xilinx and Altera tools by following the respective
|
||||
* guidelines:
|
||||
* - Xilinx UG901 Vivado Design Suite User Guide: Synthesis (p. 106)
|
||||
* - Altera Quartus II Handbook Volume 1: Design and Synthesis (p. 768)
|
||||
*
|
||||
* Current Maintainers:
|
||||
* - Michael Schaffner <schaffer@iis.ee.ethz.ch>
|
||||
*/
|
||||
|
||||
// this automatically switches the behavioral description
|
||||
// pragma translate_off
|
||||
`define SIMULATION
|
||||
// pragma translate_on
|
||||
|
||||
module SyncDpRam
|
||||
#(
|
||||
parameter ADDR_WIDTH = 10,
|
||||
parameter DATA_DEPTH = 1024, // usually 2**ADDR_WIDTH, but can be lower
|
||||
parameter DATA_WIDTH = 32,
|
||||
parameter OUT_REGS = 0,
|
||||
parameter SIM_INIT = 0 // for simulation only, will not be synthesized
|
||||
// 0: no init, 1: zero init, 2: random init
|
||||
// note: on verilator, 2 is not supported. define the VERILATOR macro to work around.
|
||||
)(
|
||||
input logic Clk_CI,
|
||||
input logic Rst_RBI,
|
||||
// port A
|
||||
input logic CSelA_SI,
|
||||
input logic WrEnA_SI,
|
||||
input logic [DATA_WIDTH-1:0] WrDataA_DI,
|
||||
input logic [ADDR_WIDTH-1:0] AddrA_DI,
|
||||
output logic [DATA_WIDTH-1:0] RdDataA_DO,
|
||||
// port B
|
||||
input logic CSelB_SI,
|
||||
input logic WrEnB_SI,
|
||||
input logic [DATA_WIDTH-1:0] WrDataB_DI,
|
||||
input logic [ADDR_WIDTH-1:0] AddrB_DI,
|
||||
output logic [DATA_WIDTH-1:0] RdDataB_DO
|
||||
);
|
||||
|
||||
////////////////////////////
|
||||
// signals, localparams
|
||||
////////////////////////////
|
||||
|
||||
logic [DATA_WIDTH-1:0] RdDataA_DN;
|
||||
logic [DATA_WIDTH-1:0] RdDataA_DP;
|
||||
logic [DATA_WIDTH-1:0] RdDataB_DN;
|
||||
logic [DATA_WIDTH-1:0] RdDataB_DP;
|
||||
logic [DATA_WIDTH-1:0] Mem_DP [DATA_DEPTH-1:0];
|
||||
|
||||
////////////////////////////
|
||||
// XILINX/ALTERA implementation
|
||||
////////////////////////////
|
||||
|
||||
`ifdef SIMULATION
|
||||
always_ff @(posedge Clk_CI)
|
||||
begin
|
||||
automatic logic [DATA_WIDTH-1:0] val;
|
||||
if(Rst_RBI == 1'b0 && SIM_INIT>0) begin
|
||||
for(int k=0; k<DATA_DEPTH;k++) begin
|
||||
if(SIM_INIT==1) val = '0;
|
||||
`ifndef VERILATOR
|
||||
else if(SIM_INIT==2) void'(randomize(val));
|
||||
`endif
|
||||
Mem_DP[k] = val;
|
||||
end
|
||||
end else begin
|
||||
if (CSelA_SI) begin
|
||||
if (WrEnA_SI) begin
|
||||
Mem_DP[AddrA_DI] <= WrDataA_DI;
|
||||
end
|
||||
else
|
||||
begin
|
||||
RdDataA_DN <= Mem_DP[AddrA_DI];
|
||||
end
|
||||
end
|
||||
|
||||
if (CSelB_SI) begin
|
||||
if (WrEnB_SI) begin
|
||||
Mem_DP[AddrB_DI] <= WrDataB_DI;
|
||||
end
|
||||
else
|
||||
begin
|
||||
RdDataB_DN <= Mem_DP[AddrB_DI];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
`endif
|
||||
|
||||
////////////////////////////
|
||||
// XILINX/ALTERA implementation
|
||||
////////////////////////////
|
||||
|
||||
`ifndef SIMULATION
|
||||
always_ff @(posedge Clk_CI)
|
||||
begin
|
||||
if (CSelA_SI) begin
|
||||
if (WrEnA_SI) begin
|
||||
Mem_DP[AddrA_DI] <= WrDataA_DI;
|
||||
end
|
||||
else
|
||||
begin
|
||||
RdDataA_DN <= Mem_DP[AddrA_DI];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge Clk_CI)
|
||||
begin
|
||||
if (CSelB_SI) begin
|
||||
if (WrEnB_SI) begin
|
||||
Mem_DP[AddrB_DI] <= WrDataB_DI;
|
||||
end
|
||||
else
|
||||
begin
|
||||
RdDataB_DN <= Mem_DP[AddrB_DI];
|
||||
end
|
||||
end
|
||||
end
|
||||
`endif
|
||||
|
||||
////////////////////////////
|
||||
// optional output regs
|
||||
////////////////////////////
|
||||
|
||||
// output regs
|
||||
generate
|
||||
if (OUT_REGS>0) begin : g_outreg
|
||||
always_ff @(posedge Clk_CI or negedge Rst_RBI) begin
|
||||
if(Rst_RBI == 1'b0)
|
||||
begin
|
||||
RdDataA_DP <= 0;
|
||||
RdDataB_DP <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
RdDataA_DP <= RdDataA_DN;
|
||||
RdDataB_DP <= RdDataB_DN;
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate // g_outreg
|
||||
|
||||
// output reg bypass
|
||||
generate
|
||||
if (OUT_REGS==0) begin : g_oureg_byp
|
||||
assign RdDataA_DP = RdDataA_DN;
|
||||
assign RdDataB_DP = RdDataB_DN;
|
||||
end
|
||||
endgenerate// g_oureg_byp
|
||||
|
||||
assign RdDataA_DO = RdDataA_DP;
|
||||
assign RdDataB_DO = RdDataB_DP;
|
||||
|
||||
////////////////////////////
|
||||
// assertions
|
||||
////////////////////////////
|
||||
|
||||
// pragma translate_off
|
||||
assert property
|
||||
(@(posedge Clk_CI) (longint'(2)**longint'(ADDR_WIDTH) >= longint'(DATA_DEPTH)))
|
||||
else $error("depth out of bounds");
|
||||
assert property
|
||||
(@(posedge Clk_CI) (CSelA_SI & CSelB_SI & WrEnA_SI & WrEnB_SI) |-> (AddrA_DI != AddrB_DI))
|
||||
else $error("A and B write to the same address");
|
||||
// pragma translate_on
|
||||
|
||||
endmodule // SyncDpRam
|
118
common/local/techlib/fpga/rtl/SyncSpRam.sv
Normal file
118
common/local/techlib/fpga/rtl/SyncSpRam.sv
Normal file
|
@ -0,0 +1,118 @@
|
|||
// Copyright 2014 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
/**
|
||||
* Inferable, Synchronous Single-Port RAM
|
||||
*
|
||||
* This module is designed to work with both Xilinx and Altera tools by following the respective
|
||||
* guidelines:
|
||||
* - Xilinx UG901 Vivado Design Suite User Guide: Synthesis (p. 106)
|
||||
* - Altera Quartus II Handbook Volume 1: Design and Synthesis (p. 768)
|
||||
*
|
||||
* Current Maintainers:
|
||||
* - Michael Schaffner <schaffer@iis.ee.ethz.ch>
|
||||
*/
|
||||
|
||||
module SyncSpRam
|
||||
#(
|
||||
parameter ADDR_WIDTH = 10,
|
||||
parameter DATA_DEPTH = 1024, // usually 2**ADDR_WIDTH, but can be lower
|
||||
parameter DATA_WIDTH = 32,
|
||||
parameter OUT_REGS = 0,
|
||||
parameter SIM_INIT = 0 // for simulation only, will not be synthesized
|
||||
// 0: no init, 1: zero init, 2: random init
|
||||
// note: on verilator, 2 is not supported. define the VERILATOR macro to work around.
|
||||
)(
|
||||
input logic Clk_CI,
|
||||
input logic Rst_RBI,
|
||||
input logic CSel_SI,
|
||||
input logic WrEn_SI,
|
||||
input logic [ADDR_WIDTH-1:0] Addr_DI,
|
||||
input logic [DATA_WIDTH-1:0] WrData_DI,
|
||||
output logic [DATA_WIDTH-1:0] RdData_DO
|
||||
);
|
||||
|
||||
////////////////////////////
|
||||
// signals, localparams
|
||||
////////////////////////////
|
||||
|
||||
logic [DATA_WIDTH-1:0] RdData_DN;
|
||||
logic [DATA_WIDTH-1:0] RdData_DP;
|
||||
logic [DATA_WIDTH-1:0] Mem_DP [DATA_DEPTH-1:0];
|
||||
|
||||
////////////////////////////
|
||||
// XILINX/ALTERA implementation
|
||||
////////////////////////////
|
||||
|
||||
always_ff @(posedge Clk_CI)
|
||||
begin
|
||||
//pragma translate_off
|
||||
automatic logic [DATA_WIDTH-1:0] val;
|
||||
if(Rst_RBI == 1'b0 && SIM_INIT>0) begin
|
||||
for(int k=0; k<DATA_DEPTH;k++) begin
|
||||
if(SIM_INIT==1) val = '0;
|
||||
`ifndef VERILATOR
|
||||
else if(SIM_INIT==2) void'(randomize(val));
|
||||
`endif
|
||||
Mem_DP[k] = val;
|
||||
end
|
||||
end else
|
||||
//pragma translate_on
|
||||
if (CSel_SI) begin
|
||||
if (WrEn_SI) begin
|
||||
Mem_DP[Addr_DI] <= WrData_DI;
|
||||
end
|
||||
else
|
||||
begin
|
||||
RdData_DN <= Mem_DP[Addr_DI];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////
|
||||
// optional output regs
|
||||
////////////////////////////
|
||||
|
||||
// output regs
|
||||
generate
|
||||
if (OUT_REGS>0) begin : g_outreg
|
||||
always_ff @(posedge Clk_CI or negedge Rst_RBI) begin
|
||||
if(Rst_RBI == 1'b0)
|
||||
begin
|
||||
RdData_DP <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
RdData_DP <= RdData_DN;
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate // g_outreg
|
||||
|
||||
// output reg bypass
|
||||
generate
|
||||
if (OUT_REGS==0) begin : g_oureg_byp
|
||||
assign RdData_DP = RdData_DN;
|
||||
end
|
||||
endgenerate// g_oureg_byp
|
||||
|
||||
assign RdData_DO = RdData_DP;
|
||||
|
||||
////////////////////////////
|
||||
// assertions
|
||||
////////////////////////////
|
||||
|
||||
// pragma translate_off
|
||||
assert property
|
||||
(@(posedge Clk_CI) (longint'(2)**longint'(ADDR_WIDTH) >= longint'(DATA_DEPTH)))
|
||||
else $error("depth out of bounds");
|
||||
// pragma translate_on
|
||||
|
||||
endmodule // SyncSpRam
|
168
common/local/techlib/fpga/rtl/SyncSpRamBeNx32.sv
Normal file
168
common/local/techlib/fpga/rtl/SyncSpRamBeNx32.sv
Normal file
|
@ -0,0 +1,168 @@
|
|||
// Copyright 2014 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
/**
|
||||
* Inferable, Synchronous Single-Port N x 32bit RAM with Byte-Wise Enable
|
||||
*
|
||||
* This module contains an implementation for either Xilinx or Altera FPGAs. To synthesize for
|
||||
* Xilinx, define `FPGA_TARGET_XILINX`. To synthesize for Altera, define `FPGA_TARGET_ALTERA`. The
|
||||
* implementations follow the respective guidelines:
|
||||
* - Xilinx UG901 Vivado Design Suite User Guide: Synthesis (p. 106)
|
||||
* - Altera Quartus II Handbook Volume 1: Design and Synthesis (p. 768)
|
||||
*
|
||||
* Current Maintainers:
|
||||
* - Michael Schaffner <schaffer@iis.ee.ethz.ch>
|
||||
*/
|
||||
|
||||
`ifndef FPGA_TARGET_ALTERA
|
||||
`define FPGA_TARGET_XILINX
|
||||
`endif
|
||||
|
||||
module SyncSpRamBeNx32
|
||||
#(
|
||||
parameter ADDR_WIDTH = 10,
|
||||
parameter DATA_DEPTH = 1024, // usually 2**ADDR_WIDTH, but can be lower
|
||||
parameter OUT_REGS = 0, // set to 1 to enable outregs
|
||||
parameter SIM_INIT = 0 // for simulation only, will not be synthesized
|
||||
// 0: no init, 1: zero init, 2: random init, 3: deadbeef init
|
||||
// note: on verilator, 2 is not supported. define the VERILATOR macro to work around.
|
||||
)(
|
||||
input logic Clk_CI,
|
||||
input logic Rst_RBI,
|
||||
input logic CSel_SI,
|
||||
input logic WrEn_SI,
|
||||
input logic [3:0] BEn_SI,
|
||||
input logic [31:0] WrData_DI,
|
||||
input logic [ADDR_WIDTH-1:0] Addr_DI,
|
||||
output logic [31:0] RdData_DO
|
||||
);
|
||||
|
||||
////////////////////////////
|
||||
// signals, localparams
|
||||
////////////////////////////
|
||||
|
||||
// needs to be consistent with the Altera implemenation below
|
||||
localparam DATA_BYTES = 4;
|
||||
|
||||
logic [DATA_BYTES*8-1:0] RdData_DN;
|
||||
logic [DATA_BYTES*8-1:0] RdData_DP;
|
||||
|
||||
////////////////////////////
|
||||
// XILINX implementation
|
||||
////////////////////////////
|
||||
|
||||
`ifdef FPGA_TARGET_XILINX
|
||||
logic [DATA_BYTES*8-1:0] Mem_DP[DATA_DEPTH-1:0];
|
||||
|
||||
always_ff @(posedge Clk_CI) begin
|
||||
//pragma translate_off
|
||||
automatic logic [31:0] val;
|
||||
if(Rst_RBI == 1'b0 && SIM_INIT>0) begin
|
||||
for(int k=0; k<DATA_DEPTH;k++) begin
|
||||
if(SIM_INIT==1) val = '0;
|
||||
`ifndef VERILATOR
|
||||
else if(SIM_INIT==2) void'(randomize(val));
|
||||
`endif
|
||||
else val = 32'hdeadbeef;
|
||||
Mem_DP[k] = val;
|
||||
end
|
||||
end else
|
||||
//pragma translate_on
|
||||
if(CSel_SI) begin
|
||||
if(WrEn_SI) begin
|
||||
if(BEn_SI[0]) Mem_DP[Addr_DI][7:0] <= WrData_DI[7:0];
|
||||
if(BEn_SI[1]) Mem_DP[Addr_DI][15:8] <= WrData_DI[15:8];
|
||||
if(BEn_SI[2]) Mem_DP[Addr_DI][23:16] <= WrData_DI[23:16];
|
||||
if(BEn_SI[3]) Mem_DP[Addr_DI][31:24] <= WrData_DI[31:24];
|
||||
end
|
||||
RdData_DN <= Mem_DP[Addr_DI];
|
||||
end
|
||||
end
|
||||
`endif
|
||||
|
||||
////////////////////////////
|
||||
// ALTERA implementation
|
||||
////////////////////////////
|
||||
|
||||
`ifdef FPGA_TARGET_ALTERA
|
||||
logic [DATA_BYTES-1:0][7:0] Mem_DP[0:DATA_DEPTH-1];
|
||||
|
||||
always_ff @(posedge Clk_CI) begin
|
||||
//pragma translate_off
|
||||
automatic logic [31:0] val;
|
||||
if(Rst_RBI == 1'b0 && SIM_INIT>0) begin
|
||||
for(int k=0; k<DATA_DEPTH;k++) begin
|
||||
if(SIM_INIT==1) val = '0;
|
||||
`ifndef VERILATOR
|
||||
else if(SIM_INIT==2) void'(randomize(val));
|
||||
`endif
|
||||
else val = 32'hdeadbeef;
|
||||
Mem_DP[k] = val;
|
||||
end
|
||||
end else
|
||||
//pragma translate_on
|
||||
if(CSel_SI) begin
|
||||
if(WrEn_SI) begin // needs to be static, otherwise Altera wont infer it
|
||||
if(BEn_SI[0]) Mem_DP[Addr_DI][0] <= WrData_DI[7:0];
|
||||
if(BEn_SI[1]) Mem_DP[Addr_DI][1] <= WrData_DI[15:8];
|
||||
if(BEn_SI[2]) Mem_DP[Addr_DI][2] <= WrData_DI[23:16];
|
||||
if(BEn_SI[3]) Mem_DP[Addr_DI][3] <= WrData_DI[31:24];
|
||||
end
|
||||
RdData_DN <= Mem_DP[Addr_DI];
|
||||
end
|
||||
end
|
||||
`endif
|
||||
|
||||
////////////////////////////
|
||||
// optional output regs
|
||||
////////////////////////////
|
||||
|
||||
// output regs
|
||||
generate
|
||||
if (OUT_REGS>0) begin : g_outreg
|
||||
always_ff @(posedge Clk_CI or negedge Rst_RBI) begin
|
||||
if(Rst_RBI == 1'b0)
|
||||
begin
|
||||
RdData_DP <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
RdData_DP <= RdData_DN;
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate // g_outreg
|
||||
|
||||
// output reg bypass
|
||||
generate
|
||||
if (OUT_REGS==0) begin : g_oureg_byp
|
||||
assign RdData_DP = RdData_DN;
|
||||
end
|
||||
endgenerate// g_oureg_byp
|
||||
|
||||
assign RdData_DO = RdData_DP;
|
||||
|
||||
////////////////////////////
|
||||
// assertions
|
||||
////////////////////////////
|
||||
|
||||
// pragma translate_off
|
||||
assert property
|
||||
(@(posedge Clk_CI) (longint'(2)**longint'(ADDR_WIDTH) >= longint'(DATA_DEPTH)))
|
||||
else $error("depth out of bounds");
|
||||
// pragma translate_on
|
||||
|
||||
`ifndef FPGA_TARGET_XILINX
|
||||
`ifndef FPGA_TARGET_ALTERA
|
||||
"FPGA target not defined, define FPGA_TARGET_XILINX or FPGA_TARGET_ALTERA."
|
||||
`endif
|
||||
`endif
|
||||
|
||||
endmodule // SyncSpRamBeNx32
|
176
common/local/techlib/fpga/rtl/SyncSpRamBeNx64.sv
Normal file
176
common/local/techlib/fpga/rtl/SyncSpRamBeNx64.sv
Normal file
|
@ -0,0 +1,176 @@
|
|||
// Copyright 2014 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
/**
|
||||
* Inferable, Synchronous Single-Port N x 64bit RAM with Byte-Wise Enable
|
||||
*
|
||||
* This module contains an implementation for either Xilinx or Altera FPGAs. To synthesize for
|
||||
* Xilinx, define `FPGA_TARGET_XILINX`. To synthesize for Altera, define `FPGA_TARGET_ALTERA`. The
|
||||
* implementations follow the respective guidelines:
|
||||
* - Xilinx UG901 Vivado Design Suite User Guide: Synthesis (p. 106)
|
||||
* - Altera Quartus II Handbook Volume 1: Design and Synthesis (p. 768)
|
||||
*
|
||||
* Current Maintainers:
|
||||
* - Michael Schaffner <schaffer@iis.ee.ethz.ch>
|
||||
*/
|
||||
|
||||
`ifndef FPGA_TARGET_ALTERA
|
||||
`define FPGA_TARGET_XILINX
|
||||
`endif
|
||||
|
||||
module SyncSpRamBeNx64
|
||||
#(
|
||||
parameter ADDR_WIDTH = 10,
|
||||
parameter DATA_DEPTH = 1024, // usually 2**ADDR_WIDTH, but can be lower
|
||||
parameter OUT_REGS = 0, // set to 1 to enable outregs
|
||||
parameter SIM_INIT = 0 // for simulation only, will not be synthesized
|
||||
// 0: no init, 1: zero init, 2: random init, 3: deadbeef init
|
||||
// note: on verilator, 2 is not supported. define the VERILATOR macro to work around.
|
||||
)(
|
||||
input logic Clk_CI,
|
||||
input logic Rst_RBI,
|
||||
input logic CSel_SI,
|
||||
input logic WrEn_SI,
|
||||
input logic [7:0] BEn_SI,
|
||||
input logic [63:0] WrData_DI,
|
||||
input logic [ADDR_WIDTH-1:0] Addr_DI,
|
||||
output logic [63:0] RdData_DO
|
||||
);
|
||||
|
||||
////////////////////////////
|
||||
// signals, localparams
|
||||
////////////////////////////
|
||||
|
||||
// needs to be consistent with the Altera implemenation below
|
||||
localparam DATA_BYTES = 8;
|
||||
|
||||
logic [DATA_BYTES*8-1:0] RdData_DN;
|
||||
logic [DATA_BYTES*8-1:0] RdData_DP;
|
||||
|
||||
////////////////////////////
|
||||
// XILINX implementation
|
||||
////////////////////////////
|
||||
|
||||
`ifdef FPGA_TARGET_XILINX
|
||||
logic [DATA_BYTES*8-1:0] Mem_DP[DATA_DEPTH-1:0];
|
||||
|
||||
always_ff @(posedge Clk_CI) begin
|
||||
//pragma translate_off
|
||||
automatic logic [63:0] val;
|
||||
if(Rst_RBI == 1'b0 && SIM_INIT>0) begin
|
||||
for(int k=0; k<DATA_DEPTH;k++) begin
|
||||
if(SIM_INIT==1) val = '0;
|
||||
`ifndef VERILATOR
|
||||
else if(SIM_INIT==2) void'(randomize(val));
|
||||
`endif
|
||||
else val = 64'hdeadbeefdeadbeef;
|
||||
Mem_DP[k] = val;
|
||||
end
|
||||
end else
|
||||
//pragma translate_on
|
||||
if(CSel_SI) begin
|
||||
if(WrEn_SI) begin
|
||||
if(BEn_SI[0]) Mem_DP[Addr_DI][7:0] <= WrData_DI[7:0];
|
||||
if(BEn_SI[1]) Mem_DP[Addr_DI][15:8] <= WrData_DI[15:8];
|
||||
if(BEn_SI[2]) Mem_DP[Addr_DI][23:16] <= WrData_DI[23:16];
|
||||
if(BEn_SI[3]) Mem_DP[Addr_DI][31:24] <= WrData_DI[31:24];
|
||||
if(BEn_SI[4]) Mem_DP[Addr_DI][39:32] <= WrData_DI[39:32];
|
||||
if(BEn_SI[5]) Mem_DP[Addr_DI][47:40] <= WrData_DI[47:40];
|
||||
if(BEn_SI[6]) Mem_DP[Addr_DI][55:48] <= WrData_DI[55:48];
|
||||
if(BEn_SI[7]) Mem_DP[Addr_DI][63:56] <= WrData_DI[63:56];
|
||||
end
|
||||
RdData_DN <= Mem_DP[Addr_DI];
|
||||
end
|
||||
end
|
||||
`endif
|
||||
|
||||
////////////////////////////
|
||||
// ALTERA implementation
|
||||
////////////////////////////
|
||||
|
||||
`ifdef FPGA_TARGET_ALTERA
|
||||
logic [DATA_BYTES-1:0][7:0] Mem_DP[0:DATA_DEPTH-1];
|
||||
|
||||
always_ff @(posedge Clk_CI) begin
|
||||
//pragma translate_off
|
||||
automatic logic [63:0] val;
|
||||
if(Rst_RBI == 1'b0 && SIM_INIT>0) begin
|
||||
for(int k=0; k<DATA_DEPTH;k++) begin
|
||||
if(SIM_INIT==1) val = '0;
|
||||
`ifndef VERILATOR
|
||||
else if(SIM_INIT==2) void'(randomize(val));
|
||||
`endif
|
||||
else val = 64'hdeadbeefdeadbeef;
|
||||
Mem_DP[k] = val;
|
||||
end
|
||||
end else
|
||||
//pragma translate_on
|
||||
if(CSel_SI) begin
|
||||
if(WrEn_SI) begin // needs to be static, otherwise Altera wont infer it
|
||||
if(BEn_SI[0]) Mem_DP[Addr_DI][0] <= WrData_DI[7:0];
|
||||
if(BEn_SI[1]) Mem_DP[Addr_DI][1] <= WrData_DI[15:8];
|
||||
if(BEn_SI[2]) Mem_DP[Addr_DI][2] <= WrData_DI[23:16];
|
||||
if(BEn_SI[3]) Mem_DP[Addr_DI][3] <= WrData_DI[31:24];
|
||||
if(BEn_SI[4]) Mem_DP[Addr_DI][4] <= WrData_DI[39:32];
|
||||
if(BEn_SI[5]) Mem_DP[Addr_DI][5] <= WrData_DI[47:40];
|
||||
if(BEn_SI[6]) Mem_DP[Addr_DI][6] <= WrData_DI[55:48];
|
||||
if(BEn_SI[7]) Mem_DP[Addr_DI][7] <= WrData_DI[63:56];
|
||||
end
|
||||
RdData_DN <= Mem_DP[Addr_DI];
|
||||
end
|
||||
end
|
||||
`endif
|
||||
|
||||
////////////////////////////
|
||||
// optional output regs
|
||||
////////////////////////////
|
||||
|
||||
// output regs
|
||||
generate
|
||||
if (OUT_REGS>0) begin : g_outreg
|
||||
always_ff @(posedge Clk_CI or negedge Rst_RBI) begin
|
||||
if(Rst_RBI == 1'b0)
|
||||
begin
|
||||
RdData_DP <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
RdData_DP <= RdData_DN;
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate // g_outreg
|
||||
|
||||
// output reg bypass
|
||||
generate
|
||||
if (OUT_REGS==0) begin : g_oureg_byp
|
||||
assign RdData_DP = RdData_DN;
|
||||
end
|
||||
endgenerate// g_oureg_byp
|
||||
|
||||
assign RdData_DO = RdData_DP;
|
||||
|
||||
////////////////////////////
|
||||
// assertions
|
||||
////////////////////////////
|
||||
|
||||
// pragma translate_off
|
||||
assert property
|
||||
(@(posedge Clk_CI) (longint'(2)**longint'(ADDR_WIDTH) >= longint'(DATA_DEPTH)))
|
||||
else $error("depth out of bounds");
|
||||
// pragma translate_on
|
||||
|
||||
`ifndef FPGA_TARGET_XILINX
|
||||
`ifndef FPGA_TARGET_ALTERA
|
||||
$error("FPGA target not defined, define FPGA_TARGET_XILINX or FPGA_TARGET_ALTERA.");
|
||||
`endif
|
||||
`endif
|
||||
|
||||
endmodule // SyncSpRamBeNx64
|
124
common/local/techlib/fpga/rtl/SyncTpRam.sv
Normal file
124
common/local/techlib/fpga/rtl/SyncTpRam.sv
Normal file
|
@ -0,0 +1,124 @@
|
|||
// Copyright 2014 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
/**
|
||||
* Inferable, Synchronous Two-Port RAM
|
||||
*
|
||||
* This RAM has a dedicated read and a dedicated write port. When reading and writing from and to
|
||||
* the same address in a single clock cycle, the read port returns the data before the write.
|
||||
*
|
||||
* This module is designed to work with both Xilinx and Altera tools by following the respective
|
||||
* guidelines:
|
||||
* - Xilinx UG901 Vivado Design Suite User Guide: Synthesis (p. 106)
|
||||
* - Altera Quartus II Handbook Volume 1: Design and Synthesis (p. 768)
|
||||
*
|
||||
* Current Maintainers:
|
||||
* - Michael Schaffner <schaffer@iis.ee.ethz.ch>
|
||||
*/
|
||||
|
||||
module SyncTpRam
|
||||
#(
|
||||
parameter ADDR_WIDTH = 10,
|
||||
parameter DATA_DEPTH = 1024, // usually 2**ADDR_WIDTH, but can be lower
|
||||
parameter DATA_WIDTH = 32,
|
||||
parameter OUT_REGS = 0,
|
||||
parameter SIM_INIT = 0 // for simulation only, will not be synthesized
|
||||
// 0: no init, 1: zero init, 2: random init
|
||||
// note: on verilator, 2 is not supported. define the VERILATOR macro to work around.
|
||||
)(
|
||||
input logic Clk_CI,
|
||||
input logic Rst_RBI,
|
||||
input logic WrEn_SI,
|
||||
input logic [ADDR_WIDTH-1:0] WrAddr_DI,
|
||||
input logic [DATA_WIDTH-1:0] WrData_DI,
|
||||
input logic RdEn_SI,
|
||||
input logic [ADDR_WIDTH-1:0] RdAddr_DI,
|
||||
output logic [DATA_WIDTH-1:0] RdData_DO
|
||||
);
|
||||
|
||||
////////////////////////////
|
||||
// signals, localparams
|
||||
////////////////////////////
|
||||
|
||||
logic [DATA_WIDTH-1:0] RdData_DN;
|
||||
logic [DATA_WIDTH-1:0] RdData_DP;
|
||||
logic [DATA_WIDTH-1:0] Mem_DP [DATA_DEPTH-1:0];
|
||||
|
||||
////////////////////////////
|
||||
// XILINX/ALTERA implementation
|
||||
////////////////////////////
|
||||
|
||||
always_ff @(posedge Clk_CI)
|
||||
begin
|
||||
//pragma translate_off
|
||||
automatic logic [DATA_WIDTH-1:0] val;
|
||||
if(Rst_RBI == 1'b0 && SIM_INIT>0) begin
|
||||
for(int k=0; k<DATA_DEPTH;k++) begin
|
||||
if(SIM_INIT==1) val = '0;
|
||||
`ifndef VERILATOR
|
||||
else if(SIM_INIT==2) void'(randomize(val));
|
||||
`endif
|
||||
Mem_DP[k] = val;
|
||||
end
|
||||
end else begin
|
||||
//pragma translate_on
|
||||
if (RdEn_SI) begin
|
||||
RdData_DN <= Mem_DP[RdAddr_DI];
|
||||
end
|
||||
if (WrEn_SI) begin
|
||||
Mem_DP[WrAddr_DI] <= WrData_DI;
|
||||
end
|
||||
//pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
end
|
||||
`endif
|
||||
//pragma translate_on
|
||||
end
|
||||
|
||||
////////////////////////////
|
||||
// optional output regs
|
||||
////////////////////////////
|
||||
|
||||
// output regs
|
||||
generate
|
||||
if (OUT_REGS>0) begin : g_outreg
|
||||
always_ff @(posedge Clk_CI or negedge Rst_RBI) begin
|
||||
if(Rst_RBI == 1'b0)
|
||||
begin
|
||||
RdData_DP <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
RdData_DP <= RdData_DN;
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate // g_outreg
|
||||
|
||||
// output reg bypass
|
||||
generate
|
||||
if (OUT_REGS==0) begin : g_oureg_byp
|
||||
assign RdData_DP = RdData_DN;
|
||||
end
|
||||
endgenerate// g_oureg_byp
|
||||
|
||||
assign RdData_DO = RdData_DP;
|
||||
|
||||
////////////////////////////
|
||||
// assertions
|
||||
////////////////////////////
|
||||
|
||||
// pragma translate_off
|
||||
assert property
|
||||
(@(posedge Clk_CI) (longint'(2)**longint'(ADDR_WIDTH) >= longint'(DATA_DEPTH)))
|
||||
else $error("depth out of bounds");
|
||||
// pragma translate_on
|
||||
|
||||
endmodule // SyncTpRam
|
|
@ -1,17 +1,17 @@
|
|||
// Copyright 2022 Thales DIS design services SAS
|
||||
// Copyright 2022 Thales Research and Technology
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Jean-Roch COULON (jean-roch.coulon@thalesgroup.com)
|
||||
// Original Author: Sébastien Jacq
|
||||
|
||||
module tc_sram_wrapper #(
|
||||
parameter int unsigned NumWords = 32'd1024, // Number of Words in data array
|
||||
parameter int unsigned DataWidth = 32'd128, // Data signal width
|
||||
parameter int unsigned ByteWidth = 32'd8, // Width of a data byte
|
||||
parameter int unsigned NumPorts = 32'd2, // Number of read and write ports
|
||||
parameter int unsigned NumPorts = 32'd1, // Number of read and write ports
|
||||
parameter int unsigned Latency = 32'd1, // Latency when the read data is available
|
||||
parameter SimInit = "none", // Simulation initialization
|
||||
parameter bit PrintSimCfg = 1'b0, // Print configuration
|
||||
|
@ -34,25 +34,25 @@ module tc_sram_wrapper #(
|
|||
output data_t [NumPorts-1:0] rdata_o // read data
|
||||
);
|
||||
|
||||
SyncSpRamBeNx64 #(
|
||||
.ADDR_WIDTH(AddrWidth),
|
||||
.DATA_DEPTH(NumWords),
|
||||
.OUT_REGS (0),
|
||||
// this initializes the memory with 0es. adjust to taste...
|
||||
// 0: no init, 1: zero init, 2: random init, 3: deadbeef init
|
||||
.SIM_INIT (1)
|
||||
) i_ram (
|
||||
.Clk_CI ( clk_i ),
|
||||
.Rst_RBI ( rst_ni ),
|
||||
.CSel_SI ( req_i[0] ),
|
||||
.WrEn_SI ( we_i[0] ),
|
||||
.BEn_SI ( be_i[0] ),
|
||||
.WrData_DI ( wdata_i[0] ),
|
||||
.Addr_DI ( addr_i[0] ),
|
||||
.RdData_DO ( rdata_o[0] )
|
||||
);
|
||||
|
||||
|
||||
tc_sram #(
|
||||
.NumWords(NumWords),
|
||||
.DataWidth(DataWidth),
|
||||
.ByteWidth(ByteWidth),
|
||||
.NumPorts(NumPorts),
|
||||
.Latency(Latency),
|
||||
.SimInit(SimInit),
|
||||
.PrintSimCfg(PrintSimCfg)
|
||||
) i_tc_sram (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.req_i ( req_i ),
|
||||
.we_i ( we_i ),
|
||||
.be_i ( be_i ),
|
||||
.wdata_i ( wdata_i ),
|
||||
.addr_i ( addr_i ),
|
||||
.rdata_o ( rdata_o )
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
|
@ -1 +0,0 @@
|
|||
Subproject commit a3ba269c0fc6cfcee6f81e5d9af018a08e479d2b
|
|
@ -4,7 +4,7 @@
|
|||
../../../core/include/ariane_pkg.sv
|
||||
../../../core/include/wt_cache_pkg.sv
|
||||
../../../common/submodules/common_cells/src/cf_math_pkg.sv
|
||||
../../fpga-support/rtl/SyncSpRamBeNx64.sv
|
||||
../../../common/local/techlib/fpga/rtl/SyncSpRamBeNx64.sv
|
||||
../../../core/cache_subsystem/cva6_icache.sv
|
||||
../../../common/submodules/common_cells/src/lfsr.sv
|
||||
../../../common/submodules/common_cells/src/fifo_v3.sv
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
../ariane_axi_soc_pkg.sv
|
||||
../../../core/include/ariane_axi_pkg.sv
|
||||
../../../core/include/std_cache_pkg.sv
|
||||
../../fpga-support/rtl/SyncSpRamBeNx64.sv
|
||||
../../../common/local/techlib/fpga/rtl/SyncSpRamBeNx64.sv
|
||||
../../../core/cache_subsystem/cache_ctrl.sv
|
||||
../../../core/cache_subsystem/miss_handler.sv
|
||||
../../../core/cache_subsystem/std_nbdcache.sv
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
../ariane_axi_soc_pkg.sv
|
||||
../../../core/include/ariane_axi_pkg.sv
|
||||
../../../core/include/wt_cache_pkg.sv
|
||||
../../fpga-support/rtl/SyncSpRamBeNx64.sv
|
||||
../../../common/local/techlib/fpga/rtl/SyncSpRamBeNx64.sv
|
||||
../../../core/cache_subsystem/wt_dcache_ctrl.sv
|
||||
../../../core/cache_subsystem/wt_dcache_mem.sv
|
||||
../../../core/cache_subsystem/wt_dcache_missunit.sv
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
../ariane_axi_soc_pkg.sv
|
||||
../../../core/include/ariane_axi_pkg.sv
|
||||
../../../core/include/wt_cache_pkg.sv
|
||||
../../fpga-support/rtl/SyncSpRamBeNx64.sv
|
||||
../../../common/local/techlib/fpga/rtl/SyncSpRamBeNx64.sv
|
||||
../../../core/cache_subsystem/wt_dcache_ctrl.sv
|
||||
../../../core/cache_subsystem/wt_dcache_mem.sv
|
||||
../../../core/cache_subsystem/wt_dcache_missunit.sv
|
||||
|
|
Loading…
Add table
Reference in a new issue