mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 13:17:41 -04:00
Start implementing Verilator wrapper
This commit is contained in:
parent
2c237d029b
commit
008af68b58
6 changed files with 334 additions and 55 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -12,3 +12,5 @@ wlft*
|
|||
src/moore.sv
|
||||
*.sig
|
||||
*.dtb
|
||||
*.dasm
|
||||
obj_dir/*
|
||||
|
|
11
Makefile
11
Makefile
|
@ -171,16 +171,19 @@ build-tests:
|
|||
cd riscv-tests && autoconf && ./configure --prefix=/home/zarubaf/riscv && make isa -j8
|
||||
|
||||
|
||||
# User Verilator to lint the target
|
||||
lint:
|
||||
verilator $(ariane_pkg) $(src) --lint-only \
|
||||
$(list_incdir) --top-module ariane
|
||||
# User Verilator
|
||||
verilate:
|
||||
verilator $(ariane_pkg) $(filter-out src/regfile.sv, $(wildcard src/*.sv)) src/util/behav_sram.sv tb/agents/axi_if/axi_if.sv \
|
||||
-Wno-fatal -LDFLAGS "-lfesvr" -Wall --cc --trace \
|
||||
$(list_incdir) --top-module ariane_wrapped --exe tb/ariane_tb.cpp tb/simmem.cpp
|
||||
cd obj_dir && make -j8 -f Variane_wrapped.mk
|
||||
|
||||
verify:
|
||||
qverify vlog -sv src/csr_regfile.sv
|
||||
|
||||
clean:
|
||||
rm -rf work/ *.ucdb
|
||||
rm -rf obj_dir
|
||||
|
||||
.PHONY:
|
||||
build lint build-moore
|
||||
|
|
|
@ -34,7 +34,6 @@ module ariane #(
|
|||
input logic fetch_enable_i,
|
||||
output logic core_busy_o,
|
||||
input logic l1_icache_miss_i,
|
||||
|
||||
// Core ID, Cluster ID and boot address are considered more or less static
|
||||
input logic [63:0] boot_addr_i,
|
||||
input logic [ 3:0] core_id_i,
|
||||
|
@ -59,7 +58,6 @@ module ariane #(
|
|||
// Timer facilities
|
||||
input logic [63:0] time_i, // global time (most probably coming from an RTC)
|
||||
input logic time_irq_i, // timer interrupt in
|
||||
|
||||
// Debug Interface
|
||||
input logic debug_req_i,
|
||||
output logic debug_gnt_o,
|
||||
|
@ -682,26 +680,53 @@ module ariane #(
|
|||
end
|
||||
end
|
||||
|
||||
endmodule // ariane
|
||||
`ifndef SYNTHESIS
|
||||
`ifndef verilator
|
||||
program instr_tracer
|
||||
(
|
||||
instruction_tracer_if tracer_if,
|
||||
input logic [5:0] cluster_id_i,
|
||||
input logic [3:0] core_id_i
|
||||
);
|
||||
|
||||
`ifndef SYNTHESIS
|
||||
program instr_tracer
|
||||
(
|
||||
instruction_tracer_if tracer_if,
|
||||
input logic [5:0] cluster_id_i,
|
||||
input logic [3:0] core_id_i
|
||||
);
|
||||
instruction_tracer it = new (tracer_if, 1'b0);
|
||||
|
||||
instruction_tracer it = new (tracer_if, 1'b0);
|
||||
initial begin
|
||||
#15ns;
|
||||
it.create_file(cluster_id_i, core_id_i);
|
||||
it.trace();
|
||||
end
|
||||
|
||||
final begin
|
||||
it.close();
|
||||
end
|
||||
endprogram
|
||||
// mock tracer
|
||||
`else
|
||||
|
||||
string s;
|
||||
int f;
|
||||
|
||||
initial begin
|
||||
#15ns;
|
||||
it.create_file(cluster_id_i, core_id_i);
|
||||
it.trace();
|
||||
f = $fopen("trace_core_0_00.dasm", "w");
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
|
||||
end else begin
|
||||
if (commit_ack && !commit_stage_i.exception_o) begin
|
||||
$fwrite(f, "0x%0h DASM(%h)\n", commit_instr_id_commit.pc, commit_instr_id_commit.ex.tval[31:0]);
|
||||
end else if (commit_ack) begin
|
||||
$fwrite(f, "Exception Cause: %5d\n", commit_instr_id_commit.ex.cause);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
final begin
|
||||
it.close();
|
||||
$fclose(f);
|
||||
end
|
||||
endprogram
|
||||
`endif
|
||||
`endif
|
||||
`endif
|
||||
endmodule // ariane
|
||||
|
||||
|
|
242
src/ariane_wrapped.sv
Normal file
242
src/ariane_wrapped.sv
Normal file
|
@ -0,0 +1,242 @@
|
|||
// Copyright 2018 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.
|
||||
//
|
||||
// Author: Florian Zaruba, ETH Zurich
|
||||
// Date: 19.03.2017
|
||||
// Description: Ariane Top-level module
|
||||
|
||||
import ariane_pkg::*;
|
||||
|
||||
import "DPI-C" function void write_mem(input longint unsigned address, input longint unsigned data);
|
||||
import "DPI-C" function longint unsigned read_mem(input longint unsigned address);
|
||||
|
||||
module ariane_wrapped #(
|
||||
parameter logic [63:0] CACHE_START_ADDR = 64'h4000_0000, // address on which to decide whether the request is cache-able or not
|
||||
parameter int unsigned AXI_ID_WIDTH = 10,
|
||||
parameter int unsigned AXI_USER_WIDTH = 1,
|
||||
parameter int unsigned AXI_ADDRESS_WIDTH = 64,
|
||||
parameter int unsigned AXI_DATA_WIDTH = 64
|
||||
)(
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic test_en_i, // enable all clock gates for testing
|
||||
|
||||
output logic flush_icache_o, // request to flush icache
|
||||
// CPU Control Signals
|
||||
input logic fetch_enable_i,
|
||||
output logic core_busy_o,
|
||||
input logic l1_icache_miss_i,
|
||||
|
||||
// Core ID, Cluster ID and boot address are considered more or less static
|
||||
input logic [63:0] boot_addr_i,
|
||||
input logic [ 3:0] core_id_i,
|
||||
input logic [ 5:0] cluster_id_i,
|
||||
// Data memory interface
|
||||
output logic [AXI_ID_WIDTH-1:0] data_if_awid_o,
|
||||
output logic [AXI_ADDRESS_WIDTH-1:0] data_if_awaddr_o,
|
||||
output logic [7:0] data_if_awlen_o,
|
||||
output logic [2:0] data_if_awsize_o,
|
||||
output logic [1:0] data_if_awburst_o,
|
||||
output logic data_if_awlock_o,
|
||||
output logic [3:0] data_if_awcache_o,
|
||||
output logic [2:0] data_if_awprot_o,
|
||||
output logic [3:0] data_if_awregion_o,
|
||||
output logic [AXI_USER_WIDTH-1:0] data_if_awuser_o,
|
||||
output logic [3:0] data_if_awqos_o,
|
||||
output logic data_if_awvalid_o,
|
||||
input logic data_if_awready_i,
|
||||
output logic [AXI_DATA_WIDTH-1:0] data_if_wdata_o,
|
||||
output logic [AXI_NUMBYTES-1:0] data_if_wstrb_o,
|
||||
output logic data_if_wlast_o,
|
||||
output logic [AXI_USER_WIDTH-1:0] data_if_wuser_o,
|
||||
output logic data_if_wvalid_o,
|
||||
input logic data_if_wready_i,
|
||||
input logic [AXI_ID_WIDTH-1:0] data_if_bid_i,
|
||||
input logic [1:0] data_if_bresp_i,
|
||||
input logic [AXI_USER_WIDTH-1:0] data_if_buser_i,
|
||||
input logic data_if_bvalid_i,
|
||||
output logic data_if_bready_o,
|
||||
output logic [AXI_ID_WIDTH-1:0] data_if_arid_o,
|
||||
output logic [AXI_ADDRESS_WIDTH-1:0] data_if_araddr_o,
|
||||
output logic [7:0] data_if_arlen_o,
|
||||
output logic [2:0] data_if_arsize_o,
|
||||
output logic [1:0] data_if_arburst_o,
|
||||
output logic data_if_arlock_o,
|
||||
output logic [3:0] data_if_arcache_o,
|
||||
output logic [2:0] data_if_arprot_o,
|
||||
output logic [3:0] data_if_arregion_o,
|
||||
output logic [AXI_USER_WIDTH-1:0] data_if_aruser_o,
|
||||
output logic [3:0] data_if_arqos_o,
|
||||
output logic data_if_arvalid_o,
|
||||
input logic data_if_arready_i,
|
||||
input logic [AXI_ID_WIDTH-1:0] data_if_rid_i,
|
||||
input logic [AXI_DATA_WIDTH-1:0] data_if_rdata_i,
|
||||
input logic [1:0] data_if_rresp_i,
|
||||
input logic data_if_rlast_i,
|
||||
input logic [AXI_USER_WIDTH-1:0] data_if_ruser_i,
|
||||
input logic data_if_rvalid_i,
|
||||
output logic data_if_rready_o,
|
||||
output logic [AXI_ID_WIDTH-1:0] bypass_if_awid_o,
|
||||
output logic [AXI_ADDRESS_WIDTH-1:0] bypass_if_awaddr_o,
|
||||
output logic [7:0] bypass_if_awlen_o,
|
||||
output logic [2:0] bypass_if_awsize_o,
|
||||
output logic [1:0] bypass_if_awburst_o,
|
||||
output logic bypass_if_awlock_o,
|
||||
output logic [3:0] bypass_if_awcache_o,
|
||||
output logic [2:0] bypass_if_awprot_o,
|
||||
output logic [3:0] bypass_if_awregion_o,
|
||||
output logic [AXI_USER_WIDTH-1:0] bypass_if_awuser_o,
|
||||
output logic [3:0] bypass_if_awqos_o,
|
||||
output logic bypass_if_awvalid_o,
|
||||
input logic bypass_if_awready_i,
|
||||
output logic [AXI_DATA_WIDTH-1:0] bypass_if_wdata_o,
|
||||
output logic [AXI_NUMBYTES-1:0] bypass_if_wstrb_o,
|
||||
output logic bypass_if_wlast_o,
|
||||
output logic [AXI_USER_WIDTH-1:0] bypass_if_wuser_o,
|
||||
output logic bypass_if_wvalid_o,
|
||||
input logic bypass_if_wready_i,
|
||||
input logic [AXI_ID_WIDTH-1:0] bypass_if_bid_i,
|
||||
input logic [1:0] bypass_if_bresp_i,
|
||||
input logic [AXI_USER_WIDTH-1:0] bypass_if_buser_i,
|
||||
input logic bypass_if_bvalid_i,
|
||||
output logic bypass_if_bready_o,
|
||||
output logic [AXI_ID_WIDTH-1:0] bypass_if_arid_o,
|
||||
output logic [AXI_ADDRESS_WIDTH-1:0] bypass_if_araddr_o,
|
||||
output logic [7:0] bypass_if_arlen_o,
|
||||
output logic [2:0] bypass_if_arsize_o,
|
||||
output logic [1:0] bypass_if_arburst_o,
|
||||
output logic bypass_if_arlock_o,
|
||||
output logic [3:0] bypass_if_arcache_o,
|
||||
output logic [2:0] bypass_if_arprot_o,
|
||||
output logic [3:0] bypass_if_arregion_o,
|
||||
output logic [AXI_USER_WIDTH-1:0] bypass_if_aruser_o,
|
||||
output logic [3:0] bypass_if_arqos_o,
|
||||
output logic bypass_if_arvalid_o,
|
||||
input logic bypass_if_arready_i,
|
||||
input logic [AXI_ID_WIDTH-1:0] bypass_if_rid_i,
|
||||
input logic [AXI_DATA_WIDTH-1:0] bypass_if_rdata_i,
|
||||
input logic [1:0] bypass_if_rresp_i,
|
||||
input logic bypass_if_rlast_i,
|
||||
input logic [AXI_USER_WIDTH-1:0] bypass_if_ruser_i,
|
||||
input logic bypass_if_rvalid_i,
|
||||
output logic bypass_if_rready_o,
|
||||
// Interrupt inputs
|
||||
input logic [1:0] irq_i, // level sensitive IR lines, mip & sip
|
||||
input logic ipi_i, // inter-processor interrupts
|
||||
input logic [4:0] irq_id_i,
|
||||
output logic irq_ack_o,
|
||||
input logic irq_sec_i,
|
||||
output logic sec_lvl_o,
|
||||
// Timer facilities
|
||||
input logic [63:0] time_i, // global time (most probably coming from an RTC)
|
||||
input logic time_irq_i, // timer interrupt in
|
||||
|
||||
// Debug Interface
|
||||
input logic debug_req_i,
|
||||
output logic debug_gnt_o,
|
||||
output logic debug_rvalid_o,
|
||||
input logic [15:0] debug_addr_i,
|
||||
input logic debug_we_i,
|
||||
input logic [63:0] debug_wdata_i,
|
||||
output logic [63:0] debug_rdata_o,
|
||||
output logic debug_halted_o,
|
||||
input logic debug_halt_i,
|
||||
input logic debug_resume_i
|
||||
);
|
||||
|
||||
localparam int unsigned AXI_NUMBYTES = AXI_DATA_WIDTH/8;
|
||||
|
||||
|
||||
logic [63:0] instr_if_address;
|
||||
logic instr_if_data_req;
|
||||
logic [3:0] instr_if_data_be;
|
||||
logic instr_if_data_gnt;
|
||||
logic instr_if_data_rvalid;
|
||||
logic [63:0] instr_if_data_rdata;
|
||||
|
||||
AXI_BUS #(
|
||||
.AXI_ADDR_WIDTH ( 64 ),
|
||||
.AXI_DATA_WIDTH ( 64 ),
|
||||
.AXI_ID_WIDTH ( AXI_ID_WIDTH ),
|
||||
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
|
||||
) data_if();
|
||||
|
||||
AXI_BUS #(
|
||||
.AXI_ADDR_WIDTH ( 64 ),
|
||||
.AXI_DATA_WIDTH ( 64 ),
|
||||
.AXI_ID_WIDTH ( AXI_ID_WIDTH ),
|
||||
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
|
||||
) bypass_if();
|
||||
|
||||
ariane #(
|
||||
.CACHE_START_ADDR ( 64'h4000_0000 ),
|
||||
.AXI_ID_WIDTH ( 10 ),
|
||||
.AXI_USER_WIDTH ( 1 )
|
||||
) i_ariane (
|
||||
.*,
|
||||
.data_if ( data_if ),
|
||||
.bypass_if ( bypass_if ),
|
||||
.instr_if_address_o ( instr_if_address ),
|
||||
.instr_if_data_req_o ( instr_if_data_req ),
|
||||
.instr_if_data_be_o ( instr_if_data_be ),
|
||||
.instr_if_data_gnt_i ( instr_if_data_gnt ),
|
||||
.instr_if_data_rvalid_i ( instr_if_data_rvalid ),
|
||||
.instr_if_data_rdata_i ( instr_if_data_rdata )
|
||||
);
|
||||
|
||||
core2mem i_core2mem (
|
||||
.instr_if_address_i ( instr_if_address ),
|
||||
.instr_if_data_req_i ( instr_if_data_req ),
|
||||
.instr_if_data_be_i ( instr_if_data_be ),
|
||||
.instr_if_data_gnt_o ( instr_if_data_gnt ),
|
||||
.instr_if_data_rvalid_o ( instr_if_data_rvalid ),
|
||||
.instr_if_data_rdata_o ( instr_if_data_rdata ),
|
||||
.bypass_if ( bypass_if ),
|
||||
.data_if ( data_if ),
|
||||
.*
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module core2mem (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
AXI_BUS.Slave bypass_if,
|
||||
AXI_BUS.Slave data_if,
|
||||
// Instruction memory interface
|
||||
input logic [63:0] instr_if_address_i,
|
||||
input logic instr_if_data_req_i,
|
||||
input logic [3:0] instr_if_data_be_i,
|
||||
output logic instr_if_data_gnt_o,
|
||||
output logic instr_if_data_rvalid_o,
|
||||
output logic [63:0] instr_if_data_rdata_o
|
||||
|
||||
);
|
||||
|
||||
|
||||
// ------------------------
|
||||
// Instruction Interface
|
||||
// ------------------------
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
instr_if_data_rvalid_o <= 1'b0;
|
||||
instr_if_data_rdata_o <= '0;
|
||||
end else begin
|
||||
// rvalid always one cycle after receiving re
|
||||
instr_if_data_rvalid_o <= instr_if_data_req_i;
|
||||
instr_if_data_rdata_o <= instr_if_data_req_i ? read_mem({instr_if_address_i[63:3], 3'b0}) : '0;
|
||||
end
|
||||
end
|
||||
|
||||
assign instr_if_data_gnt_o = instr_if_data_req_i;
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,52 +1,59 @@
|
|||
// Author: Florian Zaruba, ETH Zurich
|
||||
// Copyright 2017, 2018 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.
|
||||
//
|
||||
// Date: 13.10.2017
|
||||
// Description: SRAM Behavioral Model
|
||||
//
|
||||
// Copyright (C) 2017 ETH Zurich, University of Bologna
|
||||
// All rights reserved.
|
||||
//
|
||||
// This code is under development and not yet released to the public.
|
||||
// Until it is released, the code is under the copyright of ETH Zurich and
|
||||
// the University of Bologna, and may contain confidential and/or unpublished
|
||||
// work. Any reuse/redistribution is strictly forbidden without written
|
||||
// permission from ETH Zurich.
|
||||
//
|
||||
// Bug fixes and contributions will eventually be released under the
|
||||
// SolderPad open hardware license in the context of the PULP platform
|
||||
// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the
|
||||
// University of Bologna.
|
||||
|
||||
module sram #(
|
||||
int unsigned DATA_WIDTH = 64,
|
||||
int unsigned NUM_WORDS = 1024
|
||||
)(
|
||||
input logic clk_i,
|
||||
// Clock and Reset
|
||||
input logic clk_i,
|
||||
|
||||
input logic req_i,
|
||||
input logic [$clog2(NUM_WORDS)-1:0] addr_i,
|
||||
input logic [DATA_WIDTH-1:0] wdata_i,
|
||||
output logic [DATA_WIDTH-1:0] rdata_o,
|
||||
input logic we_i,
|
||||
input logic [DATA_WIDTH/8-1:0] be_i
|
||||
);
|
||||
|
||||
localparam words = NUM_WORDS/(DATA_WIDTH/8);
|
||||
|
||||
input logic req_i,
|
||||
input logic we_i,
|
||||
input logic [$clog2(NUM_WORDS)-1:0] addr_i,
|
||||
input logic [DATA_WIDTH-1:0] wdata_i,
|
||||
input logic [DATA_WIDTH-1:0] be_i,
|
||||
output logic [DATA_WIDTH-1:0] rdata_o
|
||||
);
|
||||
localparam ADDR_WIDTH = $clog2(NUM_WORDS);
|
||||
|
||||
logic [DATA_WIDTH-1:0] ram [NUM_WORDS-1:0];
|
||||
logic [ADDR_WIDTH-1:0] raddr_q;
|
||||
logic [DATA_WIDTH/8-1:0][7:0] mem[words];
|
||||
logic [DATA_WIDTH/8-1:0][7:0] wdata;
|
||||
logic [ADDR_WIDTH-1-$clog2(DATA_WIDTH/8):0] addr;
|
||||
|
||||
// 1. randomize array
|
||||
// 2. randomize output when no request is active
|
||||
integer i;
|
||||
|
||||
assign addr = addr_i[ADDR_WIDTH-1:$clog2(DATA_WIDTH/8)];
|
||||
|
||||
always @(posedge clk_i) begin
|
||||
if (req_i) begin
|
||||
if (!we_i)
|
||||
raddr_q <= addr_i;
|
||||
else
|
||||
for (int i = 0; i < DATA_WIDTH; i++)
|
||||
if (be_i[i]) ram[addr_i][i] <= wdata_i[i];
|
||||
if (req_i && we_i) begin
|
||||
for (i = 0; i < DATA_WIDTH/8; i++) begin
|
||||
if (be_i[i])
|
||||
mem[addr][i] <= wdata[i];
|
||||
end
|
||||
end
|
||||
|
||||
rdata_o <= mem[addr];
|
||||
end
|
||||
|
||||
assign rdata_o = ram[raddr_q];
|
||||
generate
|
||||
for (genvar w = 0; w < DATA_WIDTH/8; w++) begin
|
||||
assign wdata[w] = wdata_i[(w+1)*8-1:w*8];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
|
2
tb
2
tb
|
@ -1 +1 @@
|
|||
Subproject commit 8f1939982f58bbdc0aa8def5e641c25247ec2fb0
|
||||
Subproject commit 3f4a4efc21121277f0147540becc682e30d84761
|
Loading…
Add table
Add a link
Reference in a new issue