mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-20 12:17:19 -04:00
Linux booting to first context switch
This commit is contained in:
parent
dcc8d73aa7
commit
eab01511a3
25 changed files with 991 additions and 212 deletions
18
Makefile
18
Makefile
|
@ -58,7 +58,7 @@ src := $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \
|
|||
$(wildcard bootrom/*.sv) \
|
||||
$(wildcard src/clint/*.sv) \
|
||||
$(wildcard src/plic/*.sv) \
|
||||
$(wildcard src/register_interface/*.sv) \
|
||||
$(wildcard src/register_interface/src/*.sv) \
|
||||
$(wildcard src/axi_node/src/*.sv) \
|
||||
$(wildcard src/axi_mem_if/src/*.sv) \
|
||||
$(filter-out src/debug/dm_pkg.sv, $(wildcard src/debug/*.sv)) \
|
||||
|
@ -66,6 +66,7 @@ src := $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \
|
|||
src/axi/src/axi_multicut.sv \
|
||||
src/axi/src/axi_cut.sv \
|
||||
src/axi/src/axi_join.sv \
|
||||
src/axi/src/axi_to_axi_lite.sv \
|
||||
src/fpga-support/rtl/SyncSpRamBeNx64.sv \
|
||||
src/common_cells/src/sync.sv \
|
||||
src/common_cells/src/cdc_2phase.sv \
|
||||
|
@ -76,8 +77,9 @@ src := $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \
|
|||
src/common_cells/src/lzc.sv \
|
||||
src/common_cells/src/rrarbiter.sv \
|
||||
src/common_cells/src/lfsr_8bit.sv \
|
||||
src/common_cells/src/rstgen_bypass.sv \
|
||||
src/common_cells/src/rstgen_bypass.sv \
|
||||
tb/ariane_testharness.sv \
|
||||
tb/common/mock_uartlite.sv \
|
||||
tb/common/SimDTM.sv \
|
||||
tb/common/SimJTAG.sv
|
||||
|
||||
|
@ -148,15 +150,15 @@ sim: build
|
|||
vsim${questa_version} +permissive -64 -lib ${library} +max-cycles=$(max_cycles) +UVM_TESTNAME=${test_case} \
|
||||
+BASEDIR=$(riscv-test-dir) $(uvm-flags) "+UVM_VERBOSITY=LOW" -coverage -classdebug +jtag_rbb_enable=0 \
|
||||
$(QUESTASIM_FLAGS) \
|
||||
-gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi -do " log -r /*; run -all; exit" \
|
||||
${top_level}_optimized +permissive-off ++$(riscv-test-dir)/$(riscv-test) ++$(target-options)
|
||||
-gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi -do "log -r /*; run -all; exit" \
|
||||
${top_level}_optimized +permissive-off ++$(riscv-test-dir)$(riscv-test) ++$(target-options)
|
||||
|
||||
simc: build
|
||||
vsim${questa_version} +permissive -64 -c -lib ${library} +max-cycles=$(max_cycles) +UVM_TESTNAME=${test_case} \
|
||||
+BASEDIR=$(riscv-test-dir) $(uvm-flags) "+UVM_VERBOSITY=LOW" -coverage -classdebug +jtag_rbb_enable=0 \
|
||||
$(QUESTASIM_FLAGS) \
|
||||
-gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi -do "run -all; exit" \
|
||||
${top_level}_optimized +permissive-off ++$(riscv-test-dir)/$(riscv-test) ++$(target-options)
|
||||
-gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi -do "log -r /*; run -all; exit" \
|
||||
${top_level}_optimized +permissive-off ++$(riscv-test-dir)$(riscv-test) ++$(target-options)
|
||||
|
||||
$(riscv-asm-tests): build
|
||||
vsim${questa_version} +permissive -64 -c -lib ${library} +max-cycles=$(max_cycles) +UVM_TESTNAME=${test_case} \
|
||||
|
@ -164,7 +166,7 @@ $(riscv-asm-tests): build
|
|||
$(QUESTASIM_FLAGS) \
|
||||
-gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi \
|
||||
-do "coverage save -onexit tmp/$@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]" \
|
||||
${top_level}_optimized +permissive-off ++$(riscv-test-dir)/$@ ++$(target-options) | tee tmp/riscv-asm-tests-$@.log
|
||||
${top_level}_optimized +permissive-off ++$(riscv-test-dir)$@ ++$(target-options) | tee tmp/riscv-asm-tests-$@.log
|
||||
|
||||
$(riscv-benchmarks): build
|
||||
vsim${questa_version} +permissive -64 -c -lib ${library} +max-cycles=$(max_cycles) +UVM_TESTNAME=${test_case} \
|
||||
|
@ -172,7 +174,7 @@ $(riscv-benchmarks): build
|
|||
$(QUESTASIM_FLAGS) \
|
||||
-gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi \
|
||||
-do "coverage save -onexit tmp/$@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]" \
|
||||
${top_level}_optimized +permissive-off ++$(riscv-benchmarks-dir)/$@ ++$(target-options) | tee tmp/riscv-benchmarks-$@.log
|
||||
${top_level}_optimized +permissive-off ++$(riscv-benchmarks-dir)$@ ++$(target-options) | tee tmp/riscv-benchmarks-$@.log
|
||||
|
||||
# can use -jX to run ci tests in parallel using X processes
|
||||
run-asm-tests: $(riscv-asm-tests)
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
timebase-frequency = <50000000>;
|
||||
timebase-frequency = <25000000>;
|
||||
CPU0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
|
@ -26,7 +26,7 @@
|
|||
};
|
||||
memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x80000000 0x0 0x1000000>;
|
||||
reg = <0x0 0x80000000 0x0 0x2000000>;
|
||||
};
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
|
|
Binary file not shown.
|
@ -153,7 +153,7 @@ module bootrom (
|
|||
64'h02000000_00000000,
|
||||
64'h04000000_03000000,
|
||||
64'h00636f73_01000000,
|
||||
64'h02000000_00000001,
|
||||
64'h02000000_00000002,
|
||||
64'h00000000_00000080,
|
||||
64'h00000000_4b000000,
|
||||
64'h10000000_03000000,
|
||||
|
@ -196,7 +196,7 @@ module bootrom (
|
|||
64'h3f000000_04000000,
|
||||
64'h03000000_00000030,
|
||||
64'h40757063_01000000,
|
||||
64'h80f0fa02_2c000000,
|
||||
64'h40787d01_2c000000,
|
||||
64'h04000000_03000000,
|
||||
64'h00000000_0f000000,
|
||||
64'h04000000_03000000,
|
||||
|
|
|
@ -6,3 +6,6 @@ set_input_jitter tck 1.000
|
|||
set_max_delay -datapath_only -from [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/data_src_q_reg*/C] -to [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_dst/data_dst_q_reg*/D] 10.000
|
||||
set_max_delay -datapath_only -from [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/req_src_q_reg/C] -to [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_dst/req_dst_q_reg/D] 10.000
|
||||
set_max_delay -datapath_only -from [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_req/i_dst/ack_dst_q_reg/C] -to [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_req/i_src/ack_src_q_reg/D] 10.000
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ module ariane_leds (
|
|||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
output logic [7:0] led_o,
|
||||
input logic [3:0] pc_asserted_i,
|
||||
input logic [1:0] commit_valid_i,
|
||||
input logic dmactive_i
|
||||
);
|
||||
|
||||
|
@ -21,11 +23,12 @@ module ariane_leds (
|
|||
always_comb begin
|
||||
cnt_d = cnt_q;
|
||||
led_o = '0;
|
||||
// hearbeat
|
||||
led_o[0] = cnt_q[18];
|
||||
// debugging active
|
||||
led_o[1] = dmactive_i;
|
||||
led_o[7] = 1'b1;
|
||||
led_o[0] = pc_asserted_i[0];
|
||||
led_o[1] = pc_asserted_i[1];
|
||||
led_o[2] = pc_asserted_i[2];
|
||||
led_o[3] = pc_asserted_i[3];
|
||||
led_o[4] = commit_valid_i[0];
|
||||
led_o[5] = commit_valid_i[1];
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin : proc_
|
||||
|
|
|
@ -38,7 +38,9 @@ module ariane_xilinx (
|
|||
input logic rx,
|
||||
output logic tx,
|
||||
|
||||
output logic [7:0] led
|
||||
output logic [7:0] led,
|
||||
input logic [7:0] sw,
|
||||
output logic fan_pwm
|
||||
);
|
||||
|
||||
localparam NBSlave = 4; // debug, Instruction fetch, data bypass, data
|
||||
|
@ -86,45 +88,45 @@ logic rst_n, rst;
|
|||
logic cpu_reset;
|
||||
|
||||
// DDR
|
||||
logic [3:0] s_axi_awid;
|
||||
logic [3:0] s_axi_awid;
|
||||
logic [63:0] s_axi_awaddr;
|
||||
logic [7:0] s_axi_awlen;
|
||||
logic [2:0] s_axi_awsize;
|
||||
logic [1:0] s_axi_awburst;
|
||||
logic [0:0] s_axi_awlock;
|
||||
logic [3:0] s_axi_awcache;
|
||||
logic [2:0] s_axi_awprot;
|
||||
logic [3:0] s_axi_awregion;
|
||||
logic [3:0] s_axi_awqos;
|
||||
logic s_axi_awvalid;
|
||||
logic s_axi_awready;
|
||||
logic [7:0] s_axi_awlen;
|
||||
logic [2:0] s_axi_awsize;
|
||||
logic [1:0] s_axi_awburst;
|
||||
logic [0:0] s_axi_awlock;
|
||||
logic [3:0] s_axi_awcache;
|
||||
logic [2:0] s_axi_awprot;
|
||||
logic [3:0] s_axi_awregion;
|
||||
logic [3:0] s_axi_awqos;
|
||||
logic s_axi_awvalid;
|
||||
logic s_axi_awready;
|
||||
logic [63:0] s_axi_wdata;
|
||||
logic [7:0] s_axi_wstrb;
|
||||
logic s_axi_wlast;
|
||||
logic s_axi_wvalid;
|
||||
logic s_axi_wready;
|
||||
logic [3:0] s_axi_bid;
|
||||
logic [1:0] s_axi_bresp;
|
||||
logic s_axi_bvalid;
|
||||
logic s_axi_bready;
|
||||
logic [3:0] s_axi_arid;
|
||||
logic [7:0] s_axi_wstrb;
|
||||
logic s_axi_wlast;
|
||||
logic s_axi_wvalid;
|
||||
logic s_axi_wready;
|
||||
logic [3:0] s_axi_bid;
|
||||
logic [1:0] s_axi_bresp;
|
||||
logic s_axi_bvalid;
|
||||
logic s_axi_bready;
|
||||
logic [3:0] s_axi_arid;
|
||||
logic [63:0] s_axi_araddr;
|
||||
logic [7:0] s_axi_arlen;
|
||||
logic [2:0] s_axi_arsize;
|
||||
logic [1:0] s_axi_arburst;
|
||||
logic [0:0] s_axi_arlock;
|
||||
logic [3:0] s_axi_arcache;
|
||||
logic [2:0] s_axi_arprot;
|
||||
logic [3:0] s_axi_arregion;
|
||||
logic [3:0] s_axi_arqos;
|
||||
logic s_axi_arvalid;
|
||||
logic s_axi_arready;
|
||||
logic [3:0] s_axi_rid;
|
||||
logic [7:0] s_axi_arlen;
|
||||
logic [2:0] s_axi_arsize;
|
||||
logic [1:0] s_axi_arburst;
|
||||
logic [0:0] s_axi_arlock;
|
||||
logic [3:0] s_axi_arcache;
|
||||
logic [2:0] s_axi_arprot;
|
||||
logic [3:0] s_axi_arregion;
|
||||
logic [3:0] s_axi_arqos;
|
||||
logic s_axi_arvalid;
|
||||
logic s_axi_arready;
|
||||
logic [3:0] s_axi_rid;
|
||||
logic [63:0] s_axi_rdata;
|
||||
logic [1:0] s_axi_rresp;
|
||||
logic s_axi_rlast;
|
||||
logic s_axi_rvalid;
|
||||
logic s_axi_rready;
|
||||
logic [1:0] s_axi_rresp;
|
||||
logic s_axi_rlast;
|
||||
logic s_axi_rvalid;
|
||||
logic s_axi_rready;
|
||||
|
||||
// ROM
|
||||
logic rom_req;
|
||||
|
@ -170,6 +172,8 @@ assign rst = ddr_sync_reset;
|
|||
assign test_en = 1'b0;
|
||||
assign ndmreset_n = ~ndmreset ;
|
||||
|
||||
logic [NBSlave-1:0] pc_asserted;
|
||||
|
||||
// Slice the AXI Masters (slave ports on the XBar)
|
||||
for (genvar i = 0; i < NBSlave; i++) begin : slave_cut_gen
|
||||
axi_cut #(
|
||||
|
@ -183,6 +187,57 @@ for (genvar i = 0; i < NBSlave; i++) begin : slave_cut_gen
|
|||
.in ( slave_slice[i] ),
|
||||
.out ( slave[i] )
|
||||
);
|
||||
|
||||
axi_protocol_checker_0 i_axi_protocol_checker (
|
||||
.pc_status( ), // debug probe
|
||||
.pc_asserted(pc_asserted[i]),
|
||||
.aclk(clk),
|
||||
.aresetn(ndmreset_n),
|
||||
.pc_axi_awid(slave[i].aw_id),
|
||||
.pc_axi_awaddr(slave[i].aw_addr),
|
||||
.pc_axi_awlen(slave[i].aw_len),
|
||||
.pc_axi_awsize(slave[i].aw_size),
|
||||
.pc_axi_awburst(slave[i].aw_burst),
|
||||
.pc_axi_awlock(slave[i].aw_lock),
|
||||
.pc_axi_awcache(slave[i].aw_cache),
|
||||
.pc_axi_awprot(slave[i].aw_prot),
|
||||
.pc_axi_awqos(slave[i].aw_qos),
|
||||
.pc_axi_awregion(slave[i].aw_region),
|
||||
.pc_axi_awready(slave[i].aw_ready),
|
||||
.pc_axi_awvalid(slave[i].aw_valid),
|
||||
.pc_axi_awuser(slave[i].aw_user),
|
||||
.pc_axi_wlast(slave[i].w_last),
|
||||
.pc_axi_wdata(slave[i].w_data),
|
||||
.pc_axi_wstrb(slave[i].w_strb),
|
||||
.pc_axi_wuser(slave[i].w_user),
|
||||
.pc_axi_wvalid(slave[i].w_valid),
|
||||
.pc_axi_wready(slave[i].w_ready),
|
||||
.pc_axi_bid(slave[i].b_id),
|
||||
.pc_axi_bresp(slave[i].b_resp),
|
||||
.pc_axi_buser(slave[i].b_user),
|
||||
.pc_axi_bvalid(slave[i].b_valid),
|
||||
.pc_axi_bready(slave[i].b_ready),
|
||||
.pc_axi_arid(slave[i].ar_id),
|
||||
.pc_axi_araddr(slave[i].ar_addr),
|
||||
.pc_axi_arlen(slave[i].ar_len),
|
||||
.pc_axi_arsize(slave[i].ar_size),
|
||||
.pc_axi_arburst(slave[i].ar_burst),
|
||||
.pc_axi_arlock(slave[i].ar_lock),
|
||||
.pc_axi_arcache(slave[i].ar_cache),
|
||||
.pc_axi_arprot(slave[i].ar_prot),
|
||||
.pc_axi_arqos(slave[i].ar_qos),
|
||||
.pc_axi_arregion(slave[i].ar_region),
|
||||
.pc_axi_aruser(slave[i].ar_user),
|
||||
.pc_axi_arvalid(slave[i].ar_valid),
|
||||
.pc_axi_arready(slave[i].ar_ready),
|
||||
.pc_axi_rid(slave[i].r_id),
|
||||
.pc_axi_rlast(slave[i].r_last),
|
||||
.pc_axi_rdata(slave[i].r_data),
|
||||
.pc_axi_rresp(slave[i].r_resp),
|
||||
.pc_axi_ruser(slave[i].r_user),
|
||||
.pc_axi_rvalid(slave[i].r_valid),
|
||||
.pc_axi_rready(slave[i].r_ready)
|
||||
);
|
||||
end
|
||||
|
||||
// ---------------
|
||||
|
@ -283,7 +338,7 @@ ariane #(
|
|||
.cluster_id_i ( '0 ),
|
||||
.irq_i ( irq ),
|
||||
.ipi_i ( ipi ),
|
||||
.time_irq_i ( time_irq ),
|
||||
.time_irq_i ( timer_irq ),
|
||||
.debug_req_i ( debug_req_irq ),
|
||||
.data_if ( slave_slice[2] ),
|
||||
.bypass_if ( slave_slice[1] ),
|
||||
|
@ -293,6 +348,17 @@ ariane #(
|
|||
// ---------------
|
||||
// CLINT
|
||||
// ---------------
|
||||
logic rtc;
|
||||
|
||||
// divide clock by two
|
||||
always_ff @(posedge clk or negedge ndmreset_n) begin
|
||||
if (~ndmreset_n) begin
|
||||
rtc <= 0;
|
||||
end else begin
|
||||
rtc <= rtc ^ 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
clint #(
|
||||
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
|
||||
.AXI_DATA_WIDTH ( AxiDataWidth ),
|
||||
|
@ -302,8 +368,7 @@ clint #(
|
|||
.clk_i ( clk ),
|
||||
.rst_ni ( ndmreset_n ),
|
||||
.slave ( master[ariane_soc::CLINT] ),
|
||||
// TODO(zarubaf): Fix RTC
|
||||
.rtc_i ( 1'b0 ),
|
||||
.rtc_i ( rtc ),
|
||||
.timer_irq_o ( timer_irq ),
|
||||
.ipi_o ( ipi )
|
||||
);
|
||||
|
@ -351,18 +416,30 @@ ariane_peripherals #(
|
|||
.tx_o ( tx )
|
||||
);
|
||||
|
||||
// ---------------------
|
||||
// Board peripherals
|
||||
// ---------------------
|
||||
fan_ctrl i_fan_ctrl (
|
||||
.clk_i ( clk ),
|
||||
.rst_ni ( ndmreset_n ),
|
||||
.pwm_setting_i ( sw[3:0] ),
|
||||
.fan_pwm_o ( fan_pwm )
|
||||
);
|
||||
|
||||
ariane_leds i_ariane_leds (
|
||||
.clk_i(clk),
|
||||
.rst_ni(rst_n),
|
||||
.led_o(led),
|
||||
.dmactive_i(dmactive)
|
||||
.clk_i ( clk ),
|
||||
.rst_ni ( rst_n ),
|
||||
.led_o ( led ),
|
||||
.pc_asserted_i ( pc_asserted ),
|
||||
.dmactive_i ( dmactive ),
|
||||
.commit_valid_i ( '0 )
|
||||
);
|
||||
|
||||
clk_wiz_0 i_clk_gen (
|
||||
.clk_out1(clk),
|
||||
.reset(cpu_reset),
|
||||
.locked(), // keep open
|
||||
.clk_in1(ddr_clock_out)
|
||||
.clk_out1 ( clk ),
|
||||
.reset ( cpu_reset ),
|
||||
.locked ( ), // keep open
|
||||
.clk_in1 ( ddr_clock_out )
|
||||
);
|
||||
|
||||
// ---------------
|
||||
|
|
1
fpga/bootrom/.gitignore
vendored
Symbolic link
1
fpga/bootrom/.gitignore
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../bootrom/.gitignore
|
1
fpga/bootrom/Makefile
Symbolic link
1
fpga/bootrom/Makefile
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../bootrom/Makefile
|
65
fpga/bootrom/ariane.dts
Normal file
65
fpga/bootrom/ariane.dts
Normal file
|
@ -0,0 +1,65 @@
|
|||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
compatible = "eth,ariane-bare-dev";
|
||||
model = "eth,ariane-bare";
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
timebase-frequency = <25000000>;
|
||||
CPU0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
status = "okay";
|
||||
compatible = "riscv";
|
||||
riscv,isa = "rv64imc";
|
||||
mmu-type = "riscv,sv39";
|
||||
clock-frequency = <50000000>;
|
||||
CPU0_intc: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
compatible = "riscv,cpu-intc";
|
||||
};
|
||||
};
|
||||
};
|
||||
memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x80000000 0x0 0x2000000>;
|
||||
};
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
compatible = "eth,ariane-bare-soc", "simple-bus";
|
||||
ranges;
|
||||
clint@2000000 {
|
||||
compatible = "riscv,clint0";
|
||||
interrupts-extended = <&CPU0_intc 3 &CPU0_intc 7 >;
|
||||
reg = <0x0 0x2000000 0x0 0xc0000>;
|
||||
};
|
||||
PLIC0: interrupt-controller@c000000 {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,plic0";
|
||||
interrupt-controller;
|
||||
interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
|
||||
reg = <0x0 0xc000000 0x0 0x4000000>;
|
||||
reg-names = "control";
|
||||
riscv,max-priority = <7>;
|
||||
riscv,ndev = <53>;
|
||||
};
|
||||
debug-controller@0 {
|
||||
compatible = "riscv,debug-013";
|
||||
interrupts-extended = <&CPU0_intc 65535>;
|
||||
reg = <0x0 0x0 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
};
|
||||
uart@10000000 {
|
||||
compatible = "xlnx,axi-uartlite-1.02.a";
|
||||
reg = <0x0 0x10000000 0x0 0x10000>;
|
||||
interrupt-parent = <&PLIC0>;
|
||||
interrupts = <0 1 2>;
|
||||
clock = <50000000>;
|
||||
};
|
||||
};
|
||||
};
|
24
fpga/bootrom/bootrom.S
Normal file
24
fpga/bootrom/bootrom.S
Normal file
|
@ -0,0 +1,24 @@
|
|||
#define DRAM_BASE 0x80000000
|
||||
|
||||
.section .text.start, "ax", @progbits
|
||||
.globl _start
|
||||
_start:
|
||||
li s0, DRAM_BASE
|
||||
csrr a0, mhartid
|
||||
la a1, _dtb
|
||||
jr s0
|
||||
|
||||
.section .text.hang, "ax", @progbits
|
||||
.globl _hang
|
||||
_hang:
|
||||
csrr a0, mhartid
|
||||
la a1, _dtb
|
||||
1:
|
||||
wfi
|
||||
j 1b
|
||||
|
||||
.section .rodata.dtb, "a", @progbits
|
||||
.globl _dtb
|
||||
.align 5, 0
|
||||
_dtb:
|
||||
.incbin "ariane.dtb"
|
BIN
fpga/bootrom/bootrom.img
Normal file
BIN
fpga/bootrom/bootrom.img
Normal file
Binary file not shown.
248
fpga/bootrom/bootrom.sv
Normal file
248
fpga/bootrom/bootrom.sv
Normal file
|
@ -0,0 +1,248 @@
|
|||
/* 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.
|
||||
*
|
||||
* File: $filename.v
|
||||
*
|
||||
* Description: Auto-generated bootrom
|
||||
*/
|
||||
|
||||
// Auto-generated code
|
||||
module bootrom (
|
||||
input logic clk_i,
|
||||
input logic req_i,
|
||||
input logic [63:0] addr_i,
|
||||
output logic [63:0] rdata_o
|
||||
);
|
||||
localparam int RomSize = 211;
|
||||
|
||||
const logic [RomSize-1:0][63:0] mem = {
|
||||
64'h006b,
|
||||
64'h636f6c63_00737470,
|
||||
64'h75727265_746e6900,
|
||||
64'h746e6572_61702d74,
|
||||
64'h70757272_65746e69,
|
||||
64'h00766564_6e2c7663,
|
||||
64'h73697200_79746972,
|
||||
64'h6f697270_2d78616d,
|
||||
64'h2c766373_69720073,
|
||||
64'h656d616e_2d676572,
|
||||
64'h00646564_6e657478,
|
||||
64'h652d7374_70757272,
|
||||
64'h65746e69_00736567,
|
||||
64'h6e617200_656c646e,
|
||||
64'h6168702c_78756e69,
|
||||
64'h6c007265_6c6c6f72,
|
||||
64'h746e6f63_2d747075,
|
||||
64'h72726574_6e690073,
|
||||
64'h6c6c6563_2d747075,
|
||||
64'h72726574_6e692300,
|
||||
64'h79636e65_75716572,
|
||||
64'h662d6b63_6f6c6300,
|
||||
64'h65707974_2d756d6d,
|
||||
64'h00617369_2c766373,
|
||||
64'h69720073_75746174,
|
||||
64'h73006765_72006570,
|
||||
64'h79745f65_63697665,
|
||||
64'h64007963_6e657571,
|
||||
64'h6572662d_65736162,
|
||||
64'h656d6974_006c6564,
|
||||
64'h6f6d0065_6c626974,
|
||||
64'h61706d6f_6300736c,
|
||||
64'h6c65632d_657a6973,
|
||||
64'h2300736c_6c65632d,
|
||||
64'h73736572_64646123,
|
||||
64'h09000000_02000000,
|
||||
64'h02000000_02000000,
|
||||
64'h80f0fa02_0c010000,
|
||||
64'h04000000_03000000,
|
||||
64'h02000000_01000000,
|
||||
64'h00000000_01010000,
|
||||
64'h0c000000_03000000,
|
||||
64'h02000000_f0000000,
|
||||
64'h04000000_03000000,
|
||||
64'h00000100_00000000,
|
||||
64'h00000010_00000000,
|
||||
64'h4b000000_10000000,
|
||||
64'h03000000_00000000,
|
||||
64'h612e3230_2e312d65,
|
||||
64'h74696c74_7261752d,
|
||||
64'h6978612c_786e6c78,
|
||||
64'h1b000000_19000000,
|
||||
64'h03000000_00000030,
|
||||
64'h30303030_30303140,
|
||||
64'h74726175_01000000,
|
||||
64'h02000000_006c6f72,
|
||||
64'h746e6f63_c8000000,
|
||||
64'h08000000_03000000,
|
||||
64'h00100000_00000000,
|
||||
64'h00000000_00000000,
|
||||
64'h4b000000_10000000,
|
||||
64'h03000000_ffff0000,
|
||||
64'h01000000_b4000000,
|
||||
64'h08000000_03000000,
|
||||
64'h00333130_2d677562,
|
||||
64'h65642c76_63736972,
|
||||
64'h1b000000_10000000,
|
||||
64'h03000000_00003040,
|
||||
64'h72656c6c_6f72746e,
|
||||
64'h6f632d67_75626564,
|
||||
64'h01000000_02000000,
|
||||
64'h02000000_a5000000,
|
||||
64'h04000000_03000000,
|
||||
64'h02000000_9f000000,
|
||||
64'h04000000_03000000,
|
||||
64'h35000000_e5000000,
|
||||
64'h04000000_03000000,
|
||||
64'h07000000_d2000000,
|
||||
64'h04000000_03000000,
|
||||
64'h006c6f72_746e6f63,
|
||||
64'hc8000000_08000000,
|
||||
64'h03000000_00000004,
|
||||
64'h00000000_0000000c,
|
||||
64'h00000000_4b000000,
|
||||
64'h10000000_03000000,
|
||||
64'h09000000_01000000,
|
||||
64'h0b000000_01000000,
|
||||
64'hb4000000_10000000,
|
||||
64'h03000000_8a000000,
|
||||
64'h00000000_03000000,
|
||||
64'h00306369_6c702c76,
|
||||
64'h63736972_1b000000,
|
||||
64'h0c000000_03000000,
|
||||
64'h01000000_79000000,
|
||||
64'h04000000_03000000,
|
||||
64'h00000000_30303030,
|
||||
64'h30306340_72656c6c,
|
||||
64'h6f72746e_6f632d74,
|
||||
64'h70757272_65746e69,
|
||||
64'h01000000_02000000,
|
||||
64'h00000c00_00000000,
|
||||
64'h00000002_00000000,
|
||||
64'h4b000000_10000000,
|
||||
64'h03000000_07000000,
|
||||
64'h01000000_03000000,
|
||||
64'h01000000_b4000000,
|
||||
64'h10000000_03000000,
|
||||
64'h00000000_30746e69,
|
||||
64'h6c632c76_63736972,
|
||||
64'h1b000000_0d000000,
|
||||
64'h03000000_00000030,
|
||||
64'h30303030_30324074,
|
||||
64'h6e696c63_01000000,
|
||||
64'had000000_00000000,
|
||||
64'h03000000_00007375,
|
||||
64'h622d656c_706d6973,
|
||||
64'h00636f73_2d657261,
|
||||
64'h622d656e_61697261,
|
||||
64'h2c687465_1b000000,
|
||||
64'h1f000000_03000000,
|
||||
64'h02000000_0f000000,
|
||||
64'h04000000_03000000,
|
||||
64'h02000000_00000000,
|
||||
64'h04000000_03000000,
|
||||
64'h00636f73_01000000,
|
||||
64'h02000000_00000002,
|
||||
64'h00000000_00000080,
|
||||
64'h00000000_4b000000,
|
||||
64'h10000000_03000000,
|
||||
64'h00007972_6f6d656d,
|
||||
64'h3f000000_07000000,
|
||||
64'h03000000_00303030,
|
||||
64'h30303030_38407972,
|
||||
64'h6f6d656d_01000000,
|
||||
64'h02000000_02000000,
|
||||
64'h02000000_01000000,
|
||||
64'ha5000000_04000000,
|
||||
64'h03000000_01000000,
|
||||
64'h9f000000_04000000,
|
||||
64'h03000000_00006374,
|
||||
64'h6e692d75_70632c76,
|
||||
64'h63736972_1b000000,
|
||||
64'h0f000000_03000000,
|
||||
64'h8a000000_00000000,
|
||||
64'h03000000_01000000,
|
||||
64'h79000000_04000000,
|
||||
64'h03000000_00000000,
|
||||
64'h72656c6c_6f72746e,
|
||||
64'h6f632d74_70757272,
|
||||
64'h65746e69_01000000,
|
||||
64'h80f0fa02_69000000,
|
||||
64'h04000000_03000000,
|
||||
64'h00003933_76732c76,
|
||||
64'h63736972_60000000,
|
||||
64'h0b000000_03000000,
|
||||
64'h00636d69_34367672,
|
||||
64'h56000000_08000000,
|
||||
64'h03000000_00000076,
|
||||
64'h63736972_1b000000,
|
||||
64'h06000000_03000000,
|
||||
64'h00000000_79616b6f,
|
||||
64'h4f000000_05000000,
|
||||
64'h03000000_00000000,
|
||||
64'h4b000000_04000000,
|
||||
64'h03000000_00757063,
|
||||
64'h3f000000_04000000,
|
||||
64'h03000000_00000030,
|
||||
64'h40757063_01000000,
|
||||
64'h40787d01_2c000000,
|
||||
64'h04000000_03000000,
|
||||
64'h00000000_0f000000,
|
||||
64'h04000000_03000000,
|
||||
64'h01000000_00000000,
|
||||
64'h04000000_03000000,
|
||||
64'h00000000_73757063,
|
||||
64'h01000000_00657261,
|
||||
64'h622d656e_61697261,
|
||||
64'h2c687465_26000000,
|
||||
64'h10000000_03000000,
|
||||
64'h00766564_2d657261,
|
||||
64'h622d656e_61697261,
|
||||
64'h2c687465_1b000000,
|
||||
64'h14000000_03000000,
|
||||
64'h02000000_0f000000,
|
||||
64'h04000000_03000000,
|
||||
64'h02000000_00000000,
|
||||
64'h04000000_03000000,
|
||||
64'h00000000_01000000,
|
||||
64'h00000000_00000000,
|
||||
64'h00000000_00000000,
|
||||
64'hc8040000_12010000,
|
||||
64'h00000000_10000000,
|
||||
64'h11000000_28000000,
|
||||
64'h00050000_38000000,
|
||||
64'h12060000_edfe0dd0,
|
||||
64'h00000000_00000000,
|
||||
64'h00000000_00000000,
|
||||
64'h00000000_00000000,
|
||||
64'h00000000_00000000,
|
||||
64'h00000000_00000000,
|
||||
64'h00000000_0000bff5,
|
||||
64'h10500073_03c58593,
|
||||
64'h00000597_f1402573,
|
||||
64'h00000000_00000000,
|
||||
64'h00000000_00000000,
|
||||
64'h00000000_00000000,
|
||||
64'h00000000_00000000,
|
||||
64'h00000000_00000000,
|
||||
64'h00008402_07458593,
|
||||
64'h00000597_f1402573,
|
||||
64'h01f41413_0010041b
|
||||
};
|
||||
|
||||
logic [$clog2(RomSize)-1:0] addr_q;
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (req_i) begin
|
||||
addr_q <= addr_i[$clog2(RomSize)-1+3:3];
|
||||
end
|
||||
end
|
||||
|
||||
assign rdata_o = mem[addr_q];
|
||||
endmodule
|
1
fpga/bootrom/gen_rom.py
Symbolic link
1
fpga/bootrom/gen_rom.py
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../bootrom/gen_rom.py
|
1
fpga/bootrom/linker.ld
Symbolic link
1
fpga/bootrom/linker.ld
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../bootrom/linker.ld
|
58
fpga/fan_ctrl.sv
Normal file
58
fpga/fan_ctrl.sv
Normal file
|
@ -0,0 +1,58 @@
|
|||
// 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.
|
||||
|
||||
// Description: PWM Fan VDD
|
||||
|
||||
module fan_ctrl (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic [3:0] pwm_setting_i,
|
||||
output logic fan_pwm_o
|
||||
);
|
||||
logic [3:0] ms_clock_d, ms_clock_q;
|
||||
logic [19:0] cycle_counter_d, cycle_counter_q;
|
||||
|
||||
// clock divider
|
||||
always_comb begin
|
||||
cycle_counter_d = cycle_counter_q;
|
||||
ms_clock_d = ms_clock_q;
|
||||
|
||||
// divide clock by 499999
|
||||
if (cycle_counter_q == 499999) begin
|
||||
cycle_counter_d = 0;
|
||||
ms_clock_d = ms_clock_q + 1;
|
||||
end else begin
|
||||
cycle_counter_d = cycle_counter_q + 1;
|
||||
end
|
||||
|
||||
if (ms_clock_q == 15) begin
|
||||
ms_clock_d = 0;
|
||||
end
|
||||
end
|
||||
|
||||
// duty cycle
|
||||
always_comb begin
|
||||
if (ms_clock_q < pwm_setting_i) begin
|
||||
fan_pwm_o = 1'b1;
|
||||
end else begin
|
||||
fan_pwm_o = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
ms_clock_q <= '0;
|
||||
cycle_counter_q <= '0;
|
||||
end else begin
|
||||
ms_clock_q <= ms_clock_d;
|
||||
cycle_counter_q <= '0;
|
||||
end
|
||||
end
|
||||
endmodule
|
|
@ -1,26 +1,40 @@
|
|||
## Buttons
|
||||
set_property -dict { PACKAGE_PIN R19 IOSTANDARD LVCMOS33 } [get_ports { cpu_resetn }]; #IO_0_14 Sch=cpu_resetn
|
||||
set_property -dict {PACKAGE_PIN R19 IOSTANDARD LVCMOS33} [get_ports cpu_resetn]
|
||||
|
||||
## PMOD Header JC
|
||||
set_property -dict { PACKAGE_PIN AC26 IOSTANDARD LVCMOS33 } [get_ports { tck }]; #IO_L19P_T3_13 Sch=jc[1]
|
||||
set_property -dict { PACKAGE_PIN AJ27 IOSTANDARD LVCMOS33 } [get_ports { tdi }]; #IO_L20P_T3_13 Sch=jc[2]
|
||||
set_property -dict { PACKAGE_PIN AH30 IOSTANDARD LVCMOS33 } [get_ports { tdo }]; #IO_L18N_T2_13 Sch=jc[3]
|
||||
set_property -dict { PACKAGE_PIN AK29 IOSTANDARD LVCMOS33 } [get_ports { tms }]; #IO_L15P_T2_DQS_13 Sch=jc[4]
|
||||
set_property -dict { PACKAGE_PIN AD26 IOSTANDARD LVCMOS33 } [get_ports { trst_n }]; #IO_L19N_T3_VREF_13 Sch=jc[7]
|
||||
set_property -dict {PACKAGE_PIN AC26 IOSTANDARD LVCMOS33} [get_ports tck]
|
||||
set_property -dict {PACKAGE_PIN AJ27 IOSTANDARD LVCMOS33} [get_ports tdi]
|
||||
set_property -dict {PACKAGE_PIN AH30 IOSTANDARD LVCMOS33} [get_ports tdo]
|
||||
set_property -dict {PACKAGE_PIN AK29 IOSTANDARD LVCMOS33} [get_ports tms]
|
||||
set_property -dict {PACKAGE_PIN AD26 IOSTANDARD LVCMOS33} [get_ports trst_n]
|
||||
|
||||
## UART
|
||||
set_property -dict { PACKAGE_PIN Y23 IOSTANDARD LVCMOS33 } [get_ports { tx }]; #IO_L1P_T0_12 Sch=uart_rx_out
|
||||
set_property -dict { PACKAGE_PIN Y20 IOSTANDARD LVCMOS33 } [get_ports { rx }]; #IO_0_12 Sch=uart_tx_in
|
||||
set_property -dict {PACKAGE_PIN Y23 IOSTANDARD LVCMOS33} [get_ports tx]
|
||||
set_property -dict {PACKAGE_PIN Y20 IOSTANDARD LVCMOS33} [get_ports rx]
|
||||
|
||||
# accept sub-optimal placement
|
||||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets tck_IBUF]
|
||||
|
||||
## LEDs
|
||||
set_property -dict { PACKAGE_PIN T28 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L11N_T1_SRCC_14 Sch=led[0]
|
||||
set_property -dict { PACKAGE_PIN V19 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L19P_T3_A10_D26_14 Sch=led[1]
|
||||
set_property -dict { PACKAGE_PIN U30 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[2]
|
||||
set_property -dict { PACKAGE_PIN U29 IOSTANDARD LVCMOS33 } [get_ports { led[3] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=led[3]
|
||||
set_property -dict { PACKAGE_PIN V20 IOSTANDARD LVCMOS33 } [get_ports { led[4] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=led[4]
|
||||
set_property -dict { PACKAGE_PIN V26 IOSTANDARD LVCMOS33 } [get_ports { led[5] }]; #IO_L16P_T2_CSI_B_14 Sch=led[5]
|
||||
set_property -dict { PACKAGE_PIN W24 IOSTANDARD LVCMOS33 } [get_ports { led[6] }]; #IO_L20N_T3_A07_D23_14 Sch=led[6]
|
||||
set_property -dict { PACKAGE_PIN W23 IOSTANDARD LVCMOS33 } [get_ports { led[7] }]; #IO_L20P_T3_A08_D24_14 Sch=led[7]
|
||||
set_property -dict {PACKAGE_PIN T28 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
|
||||
set_property -dict {PACKAGE_PIN V19 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
|
||||
set_property -dict {PACKAGE_PIN U30 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
|
||||
set_property -dict {PACKAGE_PIN U29 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
|
||||
set_property -dict {PACKAGE_PIN V20 IOSTANDARD LVCMOS33} [get_ports {led[4]}]
|
||||
set_property -dict {PACKAGE_PIN V26 IOSTANDARD LVCMOS33} [get_ports {led[5]}]
|
||||
set_property -dict {PACKAGE_PIN W24 IOSTANDARD LVCMOS33} [get_ports {led[6]}]
|
||||
set_property -dict {PACKAGE_PIN W23 IOSTANDARD LVCMOS33} [get_ports {led[7]}]
|
||||
|
||||
## Switches
|
||||
set_property -dict { PACKAGE_PIN G19 IOSTANDARD LVCMOS12 } [get_ports { sw[0] }]; #IO_0_17 Sch=sw[0]
|
||||
set_property -dict { PACKAGE_PIN G25 IOSTANDARD LVCMOS12 } [get_ports { sw[1] }]; #IO_25_16 Sch=sw[1]
|
||||
set_property -dict { PACKAGE_PIN H24 IOSTANDARD LVCMOS12 } [get_ports { sw[2] }]; #IO_L19P_T3_16 Sch=sw[2]
|
||||
set_property -dict { PACKAGE_PIN K19 IOSTANDARD LVCMOS12 } [get_ports { sw[3] }]; #IO_L6P_T0_17 Sch=sw[3]
|
||||
set_property -dict { PACKAGE_PIN N19 IOSTANDARD LVCMOS12 } [get_ports { sw[4] }]; #IO_L19P_T3_A22_15 Sch=sw[4]
|
||||
set_property -dict { PACKAGE_PIN P19 IOSTANDARD LVCMOS12 } [get_ports { sw[5] }]; #IO_25_15 Sch=sw[5]
|
||||
set_property -dict { PACKAGE_PIN P26 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L10P_T1_D14_14 Sch=sw[6]
|
||||
set_property -dict { PACKAGE_PIN P27 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L8P_T1_D11_14 Sch=sw[7]
|
||||
|
||||
## Fan Control
|
||||
set_property -dict { PACKAGE_PIN W19 IOSTANDARD LVCMOS33 } [get_ports { fan_pwm }]; #IO_25_14 Sch=fan_pwm
|
||||
#set_property -dict { PACKAGE_PIN V21 IOSTANDARD LVCMOS33 } [get_ports { FAN_TACH }]; #IO_L22P_T3_A05_D21_14 Sch=fan_tac
|
|
@ -42,7 +42,7 @@ package ariane_pkg;
|
|||
| (1 << 20) // U - User mode implemented
|
||||
| (0 << 23) // X - Non-standard extensions present
|
||||
| (1 << 63); // RV64
|
||||
localparam ENABLE_RENAME = 1'b1;
|
||||
localparam ENABLE_RENAME = 1'b0;
|
||||
|
||||
// 32 registers + 1 bit for re-naming = 6
|
||||
localparam REG_ADDR_SIZE = 6;
|
||||
|
|
194
src/ariane.sv
194
src/ariane.sv
|
@ -15,7 +15,7 @@
|
|||
import ariane_pkg::*;
|
||||
`ifndef verilator
|
||||
`ifndef SYNTHESIS
|
||||
// import instruction_tracer_pkg::*;
|
||||
import instruction_tracer_pkg::*;
|
||||
`endif
|
||||
`endif
|
||||
|
||||
|
@ -566,109 +566,109 @@ module ariane #(
|
|||
// -------------------
|
||||
// Instruction Tracer
|
||||
// -------------------
|
||||
// `ifndef SYNTHESIS
|
||||
// `ifndef verilator
|
||||
// instruction_tracer_if tracer_if (clk_i);
|
||||
// // assign instruction tracer interface
|
||||
// // control signals
|
||||
// assign tracer_if.rstn = rst_ni;
|
||||
// assign tracer_if.flush_unissued = flush_unissued_instr_ctrl_id;
|
||||
// assign tracer_if.flush = flush_ctrl_ex;
|
||||
// // fetch
|
||||
// assign tracer_if.instruction = id_stage_i.compressed_decoder_i.instr_o;
|
||||
// assign tracer_if.fetch_valid = id_stage_i.instr_realigner_i.fetch_entry_valid_o;
|
||||
// assign tracer_if.fetch_ack = id_stage_i.instr_realigner_i.fetch_ack_i;
|
||||
// // Issue
|
||||
// assign tracer_if.issue_ack = issue_stage_i.i_scoreboard.issue_ack_i;
|
||||
// assign tracer_if.issue_sbe = issue_stage_i.i_scoreboard.issue_instr_o;
|
||||
// // write-back
|
||||
// assign tracer_if.waddr = waddr_commit_id;
|
||||
// assign tracer_if.wdata = wdata_commit_id;
|
||||
// assign tracer_if.we = we_commit_id;
|
||||
// // commit
|
||||
// assign tracer_if.commit_instr = commit_instr_id_commit;
|
||||
// assign tracer_if.commit_ack = commit_ack;
|
||||
// // branch predict
|
||||
// assign tracer_if.resolve_branch = resolved_branch;
|
||||
// // address translation
|
||||
// // stores
|
||||
// assign tracer_if.st_valid = ex_stage_i.lsu_i.i_store_unit.store_buffer_i.valid_i;
|
||||
// assign tracer_if.st_paddr = ex_stage_i.lsu_i.i_store_unit.store_buffer_i.paddr_i;
|
||||
// // loads
|
||||
// assign tracer_if.ld_valid = ex_stage_i.lsu_i.i_load_unit.req_port_o.tag_valid;
|
||||
// assign tracer_if.ld_kill = ex_stage_i.lsu_i.i_load_unit.req_port_o.kill_req;
|
||||
// assign tracer_if.ld_paddr = ex_stage_i.lsu_i.i_load_unit.paddr_i;
|
||||
// // exceptions
|
||||
// assign tracer_if.exception = commit_stage_i.exception_o;
|
||||
// // assign current privilege level
|
||||
// assign tracer_if.priv_lvl = priv_lvl;
|
||||
// assign tracer_if.debug_mode = debug_mode;
|
||||
// instr_tracer instr_tracer_i (tracer_if, cluster_id_i, core_id_i);
|
||||
`ifndef SYNTHESIS
|
||||
`ifndef verilator
|
||||
instruction_tracer_if tracer_if (clk_i);
|
||||
// assign instruction tracer interface
|
||||
// control signals
|
||||
assign tracer_if.rstn = rst_ni;
|
||||
assign tracer_if.flush_unissued = flush_unissued_instr_ctrl_id;
|
||||
assign tracer_if.flush = flush_ctrl_ex;
|
||||
// fetch
|
||||
assign tracer_if.instruction = id_stage_i.compressed_decoder_i.instr_o;
|
||||
assign tracer_if.fetch_valid = id_stage_i.instr_realigner_i.fetch_entry_valid_o;
|
||||
assign tracer_if.fetch_ack = id_stage_i.instr_realigner_i.fetch_ack_i;
|
||||
// Issue
|
||||
assign tracer_if.issue_ack = issue_stage_i.i_scoreboard.issue_ack_i;
|
||||
assign tracer_if.issue_sbe = issue_stage_i.i_scoreboard.issue_instr_o;
|
||||
// write-back
|
||||
assign tracer_if.waddr = waddr_commit_id;
|
||||
assign tracer_if.wdata = wdata_commit_id;
|
||||
assign tracer_if.we = we_commit_id;
|
||||
// commit
|
||||
assign tracer_if.commit_instr = commit_instr_id_commit;
|
||||
assign tracer_if.commit_ack = commit_ack;
|
||||
// branch predict
|
||||
assign tracer_if.resolve_branch = resolved_branch;
|
||||
// address translation
|
||||
// stores
|
||||
assign tracer_if.st_valid = ex_stage_i.lsu_i.i_store_unit.store_buffer_i.valid_i;
|
||||
assign tracer_if.st_paddr = ex_stage_i.lsu_i.i_store_unit.store_buffer_i.paddr_i;
|
||||
// loads
|
||||
assign tracer_if.ld_valid = ex_stage_i.lsu_i.i_load_unit.req_port_o.tag_valid;
|
||||
assign tracer_if.ld_kill = ex_stage_i.lsu_i.i_load_unit.req_port_o.kill_req;
|
||||
assign tracer_if.ld_paddr = ex_stage_i.lsu_i.i_load_unit.paddr_i;
|
||||
// exceptions
|
||||
assign tracer_if.exception = commit_stage_i.exception_o;
|
||||
// assign current privilege level
|
||||
assign tracer_if.priv_lvl = priv_lvl;
|
||||
assign tracer_if.debug_mode = debug_mode;
|
||||
instr_tracer instr_tracer_i (tracer_if, cluster_id_i, core_id_i);
|
||||
|
||||
// program instr_tracer (
|
||||
// instruction_tracer_if tracer_if,
|
||||
// input logic [5:0] cluster_id_i,
|
||||
// input logic [3:0] core_id_i
|
||||
// );
|
||||
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
|
||||
initial begin
|
||||
#15ns;
|
||||
it.create_file(cluster_id_i, core_id_i);
|
||||
it.trace();
|
||||
end
|
||||
|
||||
// final begin
|
||||
// it.close();
|
||||
// end
|
||||
// endprogram
|
||||
// // mock tracer for Verilator, to be used with spike-dasm
|
||||
// `else
|
||||
final begin
|
||||
it.close();
|
||||
end
|
||||
endprogram
|
||||
// mock tracer for Verilator, to be used with spike-dasm
|
||||
`else
|
||||
|
||||
// int f;
|
||||
// logic [63:0] cycles;
|
||||
int f;
|
||||
logic [63:0] cycles;
|
||||
|
||||
// initial begin
|
||||
// f = $fopen("trace_core_00_0.dasm", "w");
|
||||
// end
|
||||
initial begin
|
||||
f = $fopen("trace_core_00_0.dasm", "w");
|
||||
end
|
||||
|
||||
// always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
// if (~rst_ni) begin
|
||||
// cycles <= 0;
|
||||
// end else begin
|
||||
// string mode = "";
|
||||
// if (debug_mode) mode = "D";
|
||||
// else begin
|
||||
// case (priv_lvl)
|
||||
// riscv::PRIV_LVL_M: mode = "M";
|
||||
// riscv::PRIV_LVL_S: mode = "S";
|
||||
// riscv::PRIV_LVL_U: mode = "U";
|
||||
// endcase
|
||||
// end
|
||||
// for (int i = 0; i < NR_COMMIT_PORTS; i++) begin
|
||||
// if (commit_ack[i] && !commit_instr_id_commit[i].ex.valid) begin
|
||||
// $fwrite(f, "%d 0x%0h %s (0x%h) DASM(%h)\n", cycles, commit_instr_id_commit[i].pc, mode, commit_instr_id_commit[i].ex.tval[31:0], commit_instr_id_commit[i].ex.tval[31:0]);
|
||||
// end else if (commit_ack[i] && commit_instr_id_commit[i].ex.valid) begin
|
||||
// if (commit_instr_id_commit[i].ex.cause == 2) begin
|
||||
// $fwrite(f, "Exception Cause: Illegal Instructions, DASM(%h) PC=%h\n", commit_instr_id_commit[i].ex.tval[31:0], commit_instr_id_commit[i].pc);
|
||||
// end else begin
|
||||
// if (debug_mode) begin
|
||||
// $fwrite(f, "%d 0x%0h %s (0x%h) DASM(%h)\n", cycles, commit_instr_id_commit[i].pc, mode, commit_instr_id_commit[i].ex.tval[31:0], commit_instr_id_commit[i].ex.tval[31:0]);
|
||||
// end else begin
|
||||
// $fwrite(f, "Exception Cause: %5d, DASM(%h) PC=%h\n", commit_instr_id_commit[i].ex.cause, commit_instr_id_commit[i].ex.tval[31:0], commit_instr_id_commit[i].pc);
|
||||
// end
|
||||
// end
|
||||
// end
|
||||
// end
|
||||
// cycles <= cycles + 1;
|
||||
// end
|
||||
// end
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
cycles <= 0;
|
||||
end else begin
|
||||
string mode = "";
|
||||
if (debug_mode) mode = "D";
|
||||
else begin
|
||||
case (priv_lvl)
|
||||
riscv::PRIV_LVL_M: mode = "M";
|
||||
riscv::PRIV_LVL_S: mode = "S";
|
||||
riscv::PRIV_LVL_U: mode = "U";
|
||||
endcase
|
||||
end
|
||||
for (int i = 0; i < NR_COMMIT_PORTS; i++) begin
|
||||
if (commit_ack[i] && !commit_instr_id_commit[i].ex.valid) begin
|
||||
$fwrite(f, "%d 0x%0h %s (0x%h) DASM(%h)\n", cycles, commit_instr_id_commit[i].pc, mode, commit_instr_id_commit[i].ex.tval[31:0], commit_instr_id_commit[i].ex.tval[31:0]);
|
||||
end else if (commit_ack[i] && commit_instr_id_commit[i].ex.valid) begin
|
||||
if (commit_instr_id_commit[i].ex.cause == 2) begin
|
||||
$fwrite(f, "Exception Cause: Illegal Instructions, DASM(%h) PC=%h\n", commit_instr_id_commit[i].ex.tval[31:0], commit_instr_id_commit[i].pc);
|
||||
end else begin
|
||||
if (debug_mode) begin
|
||||
$fwrite(f, "%d 0x%0h %s (0x%h) DASM(%h)\n", cycles, commit_instr_id_commit[i].pc, mode, commit_instr_id_commit[i].ex.tval[31:0], commit_instr_id_commit[i].ex.tval[31:0]);
|
||||
end else begin
|
||||
$fwrite(f, "Exception Cause: %5d, DASM(%h) PC=%h\n", commit_instr_id_commit[i].ex.cause, commit_instr_id_commit[i].ex.tval[31:0], commit_instr_id_commit[i].pc);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
cycles <= cycles + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// final begin
|
||||
// $fclose(f);
|
||||
// end
|
||||
// `endif
|
||||
// `endif
|
||||
final begin
|
||||
$fclose(f);
|
||||
end
|
||||
`endif
|
||||
`endif
|
||||
endmodule // ariane
|
||||
|
||||
|
|
|
@ -34,11 +34,11 @@ package ariane_soc;
|
|||
DRAMBase = 64'h8000_0000
|
||||
} soc_bus_start_t;
|
||||
|
||||
localparam DebugLength = 64'h1000;
|
||||
localparam ROMLength = 64'h1000;
|
||||
localparam CLINTLength = 64'hC0000;
|
||||
localparam PLICLength = 64'h4000000;
|
||||
localparam UARTLength = 64'h10000;
|
||||
localparam DRAMLength = 2**24;
|
||||
|
||||
localparam logic[63:0] DebugLength = 64'h1000;
|
||||
localparam logic[63:0] ROMLength = 64'h1000;
|
||||
localparam logic[63:0] CLINTLength = 64'hC0000;
|
||||
// TODO(zarubaf): Put PLIC back 0x4000000
|
||||
localparam logic[63:0] PLICLength = 64'h40_0000;
|
||||
localparam logic[63:0] UARTLength = 64'h10000;
|
||||
localparam logic[63:0] DRAMLength = 64'h4000000;
|
||||
endpackage
|
|
@ -19,6 +19,12 @@ import uvm_pkg::*;
|
|||
|
||||
`include "uvm_macros.svh"
|
||||
|
||||
`define MAIN_MEM(P) dut.i_sram.genblk1[0].i_ram.Mem_DP[(``P``)]
|
||||
|
||||
import "DPI-C" function read_elf(input string filename);
|
||||
import "DPI-C" function byte get_section(output longint address, output longint len);
|
||||
import "DPI-C" context function byte read_section(input longint address, inout byte buffer[]);
|
||||
|
||||
module ariane_tb;
|
||||
|
||||
// static uvm_cmdline_processor uvcl = uvm_cmdline_processor::get_inst();
|
||||
|
@ -27,6 +33,7 @@ module ariane_tb;
|
|||
// toggle with half the clock period
|
||||
localparam int unsigned RTC_CLOCK_PERIOD = CLOCK_PERIOD/2;
|
||||
|
||||
localparam NUM_WORDS = 2**25;
|
||||
logic clk_i;
|
||||
logic rst_ni;
|
||||
logic rtc_i;
|
||||
|
@ -36,7 +43,9 @@ module ariane_tb;
|
|||
|
||||
logic [31:0] exit_o;
|
||||
|
||||
ariane_testharness dut (
|
||||
ariane_testharness #(
|
||||
.NUM_WORDS ( NUM_WORDS )
|
||||
) dut (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.rtc_i,
|
||||
|
@ -83,4 +92,39 @@ module ariane_tb;
|
|||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
automatic string BINARY = "/scratch/zarubaf/ariane/fpga/bbl";
|
||||
automatic logic [7:0][7:0] mem_row;
|
||||
longint address, len;
|
||||
byte buffer[];
|
||||
`uvm_info( "Core Test", "Zeroing memory", UVM_LOW)
|
||||
|
||||
// avoid X pesimism
|
||||
for (int i = 0; i < NUM_WORDS; i++) begin
|
||||
`MAIN_MEM(i) = '0;
|
||||
end
|
||||
|
||||
`uvm_info( "Core Test", $sformatf("Loading ELF: %s", BINARY), UVM_LOW)
|
||||
|
||||
void'(read_elf(BINARY));
|
||||
|
||||
// while there are more sections to process
|
||||
while (get_section(address, len)) begin
|
||||
`uvm_info( "Core Test", $sformatf("Loading Address: %x, Length: %x", address, len), UVM_LOW)
|
||||
buffer = new [len];
|
||||
void'(read_section(address, buffer));
|
||||
// preload memories
|
||||
// 64-bit
|
||||
for (int i = 0; i < buffer.size()/8; i++) begin
|
||||
mem_row = '0;
|
||||
for (int j = 0; j < 8; j++) begin
|
||||
mem_row[j] = buffer[i*8 + j];
|
||||
end
|
||||
|
||||
`MAIN_MEM((address[28:0] >> 3) + i) = mem_row;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -14,18 +14,18 @@
|
|||
// Instantiates an AXI-Bus and memories
|
||||
|
||||
module ariane_testharness #(
|
||||
parameter logic [63:0] CACHE_START_ADDR = 64'h8000_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,
|
||||
parameter int unsigned NUM_WORDS = 2**24 // memory size
|
||||
)(
|
||||
input logic clk_i,
|
||||
input logic rtc_i,
|
||||
input logic rst_ni,
|
||||
output logic [31:0] exit_o
|
||||
);
|
||||
parameter logic [63:0] CACHE_START_ADDR = 64'h8000_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,
|
||||
parameter int unsigned NUM_WORDS = 2**25 // memory size
|
||||
)(
|
||||
input logic clk_i,
|
||||
input logic rtc_i,
|
||||
input logic rst_ni,
|
||||
output logic [31:0] exit_o
|
||||
);
|
||||
|
||||
// disable test-enable
|
||||
logic test_en;
|
||||
|
@ -296,6 +296,16 @@ module ariane_testharness #(
|
|||
// ---------------
|
||||
logic ipi;
|
||||
logic timer_irq;
|
||||
logic rtc;
|
||||
|
||||
// divide clock by two
|
||||
always_ff @(posedge clk_i or negedge ndmreset_n) begin
|
||||
if (~ndmreset_n) begin
|
||||
rtc <= 0;
|
||||
end else begin
|
||||
rtc <= rtc ^ 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
clint #(
|
||||
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
|
||||
|
@ -304,9 +314,9 @@ module ariane_testharness #(
|
|||
.NR_CORES ( 1 )
|
||||
) i_clint (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.rst_ni ( ndmreset_n ),
|
||||
.slave ( master[ariane_soc::CLINT] ),
|
||||
.rtc_i,
|
||||
.rtc_i ( rtc ),
|
||||
.timer_irq_o ( timer_irq ),
|
||||
.ipi_o ( ipi )
|
||||
);
|
||||
|
@ -317,11 +327,34 @@ module ariane_testharness #(
|
|||
logic [ariane_soc::NumTargets-1:0] irqs;
|
||||
logic [ariane_soc::NumSources-1:0] irq_sources;
|
||||
|
||||
AXI_LITE #(
|
||||
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
|
||||
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH )
|
||||
) axi_lite_plic ();
|
||||
|
||||
REG_BUS #(
|
||||
.ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
|
||||
.DATA_WIDTH ( AXI_DATA_WIDTH )
|
||||
) reg_bus (clk_i);
|
||||
|
||||
axi_to_axi_lite i_axi_to_axi_lite_eth (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.testmode_i ( 1'b0 ),
|
||||
.in ( master[ariane_soc::PLIC] ),
|
||||
.out ( axi_lite_plic )
|
||||
);
|
||||
|
||||
axi_lite_to_reg #(
|
||||
.ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
|
||||
.DATA_WIDTH ( AXI_DATA_WIDTH )
|
||||
) i_axi_lite_to_reg (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.axi_i ( axi_lite_plic ), // AXI Lite
|
||||
.reg_o ( reg_bus )
|
||||
);
|
||||
|
||||
plic #(
|
||||
.ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
|
||||
.DATA_WIDTH ( AXI_DATA_WIDTH ),
|
||||
|
@ -340,14 +373,9 @@ module ariane_testharness #(
|
|||
// ---------------
|
||||
// Peripheral
|
||||
// ---------------
|
||||
|
||||
mock_uartlite i_mock_uartlite (.clk_i(clk_i), .rst_ni(rst_ni), .slave(master[ariane_soc::UART]));
|
||||
// tie-off uart here
|
||||
assign irq_sources = '0;
|
||||
assign master[ariane_soc::UART].aw_ready = 1'b1;
|
||||
assign master[ariane_soc::UART].ar_ready = 1'b1;
|
||||
assign master[ariane_soc::UART].w_ready = 1'b1;
|
||||
assign master[ariane_soc::UART].b_valid = 1'b0;
|
||||
assign master[ariane_soc::UART].r_valid = 1'b0;
|
||||
|
||||
// ---------------
|
||||
// Core
|
||||
|
|
74
tb/common/mock_uartlite.sv
Normal file
74
tb/common/mock_uartlite.sv
Normal file
|
@ -0,0 +1,74 @@
|
|||
// 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: 28/09/2018
|
||||
// Description: Mock replacement for UART in testbench
|
||||
|
||||
module mock_uartlite (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni,
|
||||
AXI_BUS.Slave slave
|
||||
);
|
||||
|
||||
// string buffer
|
||||
byte buffer [$];
|
||||
|
||||
function void flush();
|
||||
string s;
|
||||
// dump the buffer out the whole buffer
|
||||
foreach (buffer[i]) begin
|
||||
s = $sformatf("%s%c",s, buffer[i]);
|
||||
end
|
||||
|
||||
$display(s);
|
||||
|
||||
// clear buffer afterwards
|
||||
buffer = {};
|
||||
endfunction : flush
|
||||
|
||||
// put a char to the buffer
|
||||
function void append(byte ch);
|
||||
|
||||
// wait for the new line
|
||||
if (ch == 8'hA)
|
||||
flush();
|
||||
else
|
||||
buffer.push_back(ch);
|
||||
|
||||
endfunction : append
|
||||
|
||||
logic req_o;
|
||||
logic we_o;
|
||||
logic [63:0] addr_o;
|
||||
logic [64/8-1:0] be_o;
|
||||
logic [63:0] data_o;
|
||||
|
||||
axi2mem #(
|
||||
.AXI_ID_WIDTH($bits(slave.aw_id)),
|
||||
.AXI_USER_WIDTH($bits(slave.aw_user))
|
||||
) i_axi2mem (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.slave ( slave ),
|
||||
.req_o ( req_o ),
|
||||
.we_o ( we_o ),
|
||||
.addr_o ( addr_o ),
|
||||
.be_o ( be_o ),
|
||||
.data_o ( data_o ),
|
||||
.data_i ( '0 )
|
||||
);
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (rst_ni) begin
|
||||
if (req_o & we_o & addr_o[3:0] == 'h4) append(byte'(data_o[40:32]));
|
||||
end
|
||||
end
|
||||
endmodule
|
|
@ -13,17 +13,14 @@
|
|||
// Description: This module takes data over UART and prints them to the console
|
||||
// A string is printed to the console as soon as a '\n' character is found
|
||||
|
||||
interface uart_bus
|
||||
#(
|
||||
interface uart_bus #(
|
||||
parameter BAUD_RATE = 115200,
|
||||
parameter PARITY_EN = 0
|
||||
)
|
||||
(
|
||||
)(
|
||||
input logic rx,
|
||||
output logic tx,
|
||||
|
||||
input logic rx_en
|
||||
);
|
||||
);
|
||||
|
||||
localparam BIT_PERIOD = (1000000000/BAUD_RATE*1000);
|
||||
|
||||
|
|
138
tb/dpi/elfloader.cc
Normal file
138
tb/dpi/elfloader.cc
Normal file
|
@ -0,0 +1,138 @@
|
|||
// #include "elfloader.h"
|
||||
|
||||
#include <fesvr/elf.h>
|
||||
#include <fesvr/memif.h>
|
||||
|
||||
#include <svdpi.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
#define SHT_PROGBITS 0x1
|
||||
#define SHT_GROUP 0x11
|
||||
|
||||
// address and size
|
||||
std::vector<std::pair<reg_t, reg_t>> sections;
|
||||
std::map<std::string, uint64_t> symbols;
|
||||
// memory based address and content
|
||||
std::map<reg_t, std::vector<uint8_t>> mems;
|
||||
reg_t entry;
|
||||
int section_index = 0;
|
||||
|
||||
void write (uint64_t address, uint64_t len, uint8_t* buf) {
|
||||
uint64_t datum;
|
||||
std::vector<uint8_t> mem;
|
||||
for (int i = 0; i < len; i++) {
|
||||
mem.push_back(buf[i]);
|
||||
}
|
||||
mems.insert(std::make_pair(address, mem));
|
||||
}
|
||||
|
||||
// Communicate the section address and len
|
||||
// Returns:
|
||||
// 0 if there are no more sections
|
||||
// 1 if there are more sections to load
|
||||
extern "C" char get_section (long long* address, long long* len) {
|
||||
if (section_index < sections.size()) {
|
||||
*address = sections[section_index].first;
|
||||
*len = sections[section_index].second;
|
||||
section_index++;
|
||||
return 1;
|
||||
} else return 0;
|
||||
}
|
||||
|
||||
extern "C" char read_section (long long address, const svOpenArrayHandle buffer) {
|
||||
// get actual poitner
|
||||
void* buf = svGetArrayPtr(buffer);
|
||||
// check that the address points to a section
|
||||
assert(mems.count(address) > 0);
|
||||
// copy array
|
||||
int i = 0;
|
||||
for (auto &datum : mems.find(address)->second) {
|
||||
*((char *) buf + i) = datum;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void read_elf(const char* filename) {
|
||||
int fd = open(filename, O_RDONLY);
|
||||
struct stat s;
|
||||
assert(fd != -1);
|
||||
if (fstat(fd, &s) < 0)
|
||||
abort();
|
||||
size_t size = s.st_size;
|
||||
|
||||
char* buf = (char*)mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
assert(buf != MAP_FAILED);
|
||||
close(fd);
|
||||
|
||||
assert(size >= sizeof(Elf64_Ehdr));
|
||||
const Elf64_Ehdr* eh64 = (const Elf64_Ehdr*)buf;
|
||||
assert(IS_ELF32(*eh64) || IS_ELF64(*eh64));
|
||||
|
||||
|
||||
|
||||
std::vector<uint8_t> zeros;
|
||||
std::map<std::string, uint64_t> symbols;
|
||||
|
||||
#define LOAD_ELF(ehdr_t, phdr_t, shdr_t, sym_t) do { \
|
||||
ehdr_t* eh = (ehdr_t*)buf; \
|
||||
phdr_t* ph = (phdr_t*)(buf + eh->e_phoff); \
|
||||
entry = eh->e_entry; \
|
||||
assert(size >= eh->e_phoff + eh->e_phnum*sizeof(*ph)); \
|
||||
for (unsigned i = 0; i < eh->e_phnum; i++) { \
|
||||
if(ph[i].p_type == PT_LOAD && ph[i].p_memsz) { \
|
||||
if (ph[i].p_filesz) { \
|
||||
assert(size >= ph[i].p_offset + ph[i].p_filesz); \
|
||||
sections.push_back(std::make_pair(ph[i].p_paddr, ph[i].p_memsz)); \
|
||||
write(ph[i].p_paddr, ph[i].p_filesz, (uint8_t*)buf + ph[i].p_offset); \
|
||||
} \
|
||||
zeros.resize(ph[i].p_memsz - ph[i].p_filesz); \
|
||||
} \
|
||||
} \
|
||||
shdr_t* sh = (shdr_t*)(buf + eh->e_shoff); \
|
||||
assert(size >= eh->e_shoff + eh->e_shnum*sizeof(*sh)); \
|
||||
assert(eh->e_shstrndx < eh->e_shnum); \
|
||||
assert(size >= sh[eh->e_shstrndx].sh_offset + sh[eh->e_shstrndx].sh_size); \
|
||||
char *shstrtab = buf + sh[eh->e_shstrndx].sh_offset; \
|
||||
unsigned strtabidx = 0, symtabidx = 0; \
|
||||
for (unsigned i = 0; i < eh->e_shnum; i++) { \
|
||||
unsigned max_len = sh[eh->e_shstrndx].sh_size - sh[i].sh_name; \
|
||||
if ((sh[i].sh_type & SHT_GROUP) && strcmp(shstrtab + sh[i].sh_name, ".strtab") != 0 && strcmp(shstrtab + sh[i].sh_name, ".shstrtab") != 0) \
|
||||
assert(strnlen(shstrtab + sh[i].sh_name, max_len) < max_len); \
|
||||
if (sh[i].sh_type & SHT_PROGBITS) continue; \
|
||||
assert(size >= sh[i].sh_offset + sh[i].sh_size); \
|
||||
if (strcmp(shstrtab + sh[i].sh_name, ".strtab") == 0) \
|
||||
strtabidx = i; \
|
||||
if (strcmp(shstrtab + sh[i].sh_name, ".symtab") == 0) \
|
||||
symtabidx = i; \
|
||||
} \
|
||||
if (strtabidx && symtabidx) { \
|
||||
char* strtab = buf + sh[strtabidx].sh_offset; \
|
||||
sym_t* sym = (sym_t*)(buf + sh[symtabidx].sh_offset); \
|
||||
for (unsigned i = 0; i < sh[symtabidx].sh_size/sizeof(sym_t); i++) { \
|
||||
unsigned max_len = sh[strtabidx].sh_size - sym[i].st_name; \
|
||||
assert(sym[i].st_name < sh[strtabidx]. sh_size); \
|
||||
assert(strnlen(strtab + sym[i].st_name, max_len) < max_len); \
|
||||
symbols[strtab + sym[i].st_name] = sym[i].st_value; \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
if (IS_ELF32(*eh64))
|
||||
LOAD_ELF(Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Sym);
|
||||
else
|
||||
LOAD_ELF(Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Sym);
|
||||
|
||||
munmap(buf, size);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue