mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-20 12:17:19 -04:00
Merge pull request #161 from msfschaffner/dm-reloc-fix
This patch makes the dm relocatable to an arbitrary base address.
This commit is contained in:
commit
424d6302d3
15 changed files with 150 additions and 93 deletions
|
@ -122,7 +122,6 @@ src/cache_subsystem/serpent_dcache.sv
|
|||
src/cache_subsystem/serpent_icache.sv
|
||||
src/cache_subsystem/serpent_l15_adapter.sv
|
||||
src/cache_subsystem/serpent_cache_subsystem.sv
|
||||
src/debug/debug_rom/debug_rom.sv
|
||||
src/debug/dm_csrs.sv
|
||||
src/clint/clint.sv
|
||||
src/clint/axi_lite_interface.sv
|
||||
|
@ -134,6 +133,7 @@ src/debug/dm_sba.sv
|
|||
src/debug/dmi_jtag_tap.sv
|
||||
openpiton/ariane_verilog_wrap.sv
|
||||
openpiton/serpent_peripherals.sv
|
||||
openpiton/debug_rom/debug_rom.sv
|
||||
bootrom/bootrom.sv
|
||||
src/plic/plic.sv
|
||||
src/plic/plic_claim_complete_tracker.sv
|
||||
|
@ -154,4 +154,4 @@ fpga/src/axi_slice/src/axi_ar_buffer.sv
|
|||
fpga/src/axi_slice/src/axi_r_buffer.sv
|
||||
fpga/src/axi_slice/src/axi_aw_buffer.sv
|
||||
src/register_interface/src/apb_to_reg.sv
|
||||
src/register_interface/src/reg_intf.sv
|
||||
src/register_interface/src/reg_intf.sv
|
||||
|
|
|
@ -833,7 +833,7 @@
|
|||
#define CSR_DPC 0x7b1
|
||||
#define CSR_DSCRATCH 0x7b2
|
||||
#define CSR_DSCRATCH0 CSR_DSCRATCH
|
||||
#define CSR_DSCRATCH1 0x7b2
|
||||
#define CSR_DSCRATCH1 0x7b3
|
||||
#define CSR_MCYCLE 0xb00
|
||||
#define CSR_MINSTRET 0xb02
|
||||
#define CSR_MHPMCOUNTER3 0xb03
|
||||
|
|
|
@ -85,8 +85,9 @@ def read_bin():
|
|||
except Exception as e:
|
||||
pass
|
||||
|
||||
|
||||
# align to 64 bit
|
||||
align = (int(len(rom) / 8) + 1) * 8;
|
||||
align = (int((len(rom) + 7) / 8 )) * 8;
|
||||
|
||||
for i in range(len(rom), align):
|
||||
rom.append("00")
|
||||
|
|
|
@ -367,6 +367,7 @@ package riscv;
|
|||
CSR_DPC = 12'h7b1,
|
||||
CSR_DSCRATCH0 = 12'h7b2, // optional
|
||||
CSR_DSCRATCH1 = 12'h7b3, // optional
|
||||
|
||||
// Counters and Timers
|
||||
CSR_CYCLE = 12'hC00,
|
||||
CSR_TIME = 12'hC01,
|
||||
|
@ -486,11 +487,31 @@ package riscv;
|
|||
return {offset[11:0], rs1, 3'b0, rd, 7'h67};
|
||||
endfunction
|
||||
|
||||
function automatic logic [31:0] andi (logic[4:0] rd, logic[4:0] rs1, logic [11:0] imm);
|
||||
// OpCode andi
|
||||
return {imm[11:0], rs1, 3'h7, rd, 7'h13};
|
||||
endfunction
|
||||
|
||||
function automatic logic [31:0] slli (logic[4:0] rd, logic[4:0] rs1, logic [5:0] shamt);
|
||||
// OpCode slli
|
||||
return {6'b0, shamt[5:0], rs1, 3'h1, rd, 7'h13};
|
||||
endfunction
|
||||
|
||||
function automatic logic [31:0] srli (logic[4:0] rd, logic[4:0] rs1, logic [5:0] shamt);
|
||||
// OpCode srli
|
||||
return {6'b0, shamt[5:0], rs1, 3'h5, rd, 7'h13};
|
||||
endfunction
|
||||
|
||||
function automatic logic [31:0] load (logic [2:0] size, logic[4:0] dest, logic[4:0] base, logic [11:0] offset);
|
||||
// OpCode Load
|
||||
return {offset[11:0], base, size, dest, 7'h03};
|
||||
endfunction
|
||||
|
||||
function automatic logic [31:0] auipc (logic[4:0] rd, logic [20:0] imm);
|
||||
// OpCode Auipc
|
||||
return {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h17};
|
||||
endfunction
|
||||
|
||||
function automatic logic [31:0] store (logic [2:0] size, logic[4:0] src, logic[4:0] base, logic [11:0] offset);
|
||||
// OpCode Store
|
||||
return {offset[11:5], src, base, size, offset[4:0], 7'h23};
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
`endif
|
||||
|
||||
module ariane_verilog_wrap #(
|
||||
parameter logic [63:0] DmBaseAddress = 64'h0, // debug module base address
|
||||
parameter bit SwapEndianess = 1, // swap endianess in l15 adapter
|
||||
parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000, // end of cached region
|
||||
parameter logic [63:0] CachedAddrBeg = 64'h00_8000_0000 // begin of cached region
|
||||
|
@ -58,21 +59,10 @@ module ariane_verilog_wrap #(
|
|||
assign axi_resp = axi_resp_i;
|
||||
`else
|
||||
// L15 (memory side)
|
||||
serpent_cache_pkg::l15_req_t l15_req, l15_req_remapped;
|
||||
serpent_cache_pkg::l15_req_t l15_req;
|
||||
serpent_cache_pkg::l15_rtrn_t l15_rtrn;
|
||||
|
||||
/////////////////////////////
|
||||
// Debug module address translation
|
||||
/////////////////////////////
|
||||
|
||||
always_comb begin : p_remap
|
||||
l15_req_remapped = l15_req;
|
||||
if (l15_req.l15_address < 64'h1000) begin
|
||||
l15_req_remapped.l15_address = l15_req.l15_address + 64'hfff1000000;
|
||||
end
|
||||
end
|
||||
|
||||
assign l15_req_o = l15_req_remapped;
|
||||
assign l15_req_o = l15_req;
|
||||
assign l15_rtrn = l15_rtrn_i;
|
||||
`endif
|
||||
|
||||
|
@ -168,6 +158,7 @@ module ariane_verilog_wrap #(
|
|||
/////////////////////////////
|
||||
|
||||
ariane #(
|
||||
.DmBaseAddress ( DmBaseAddress ),
|
||||
.SwapEndianess ( SwapEndianess ),
|
||||
.CachedAddrEnd ( CachedAddrEnd ),
|
||||
.CachedAddrBeg ( CachedAddrBeg )
|
||||
|
|
|
@ -28,6 +28,7 @@ import instruction_tracer_pkg::*;
|
|||
`endif
|
||||
|
||||
module ariane #(
|
||||
parameter logic [63:0] DmBaseAddress = 64'h0, // debug module base address
|
||||
`ifdef PITON_ARIANE
|
||||
parameter bit SwapEndianess = 0, // swap endianess in l15 adapter
|
||||
parameter logic [63:0] CachedAddrEnd = 64'h80_0000_0000, // end of cached region
|
||||
|
@ -239,7 +240,9 @@ module ariane #(
|
|||
// --------------
|
||||
// Frontend
|
||||
// --------------
|
||||
frontend i_frontend (
|
||||
frontend #(
|
||||
.DmBaseAddress ( DmBaseAddress )
|
||||
) i_frontend (
|
||||
.flush_i ( flush_ctrl_if ), // not entirely correct
|
||||
.flush_bp_i ( 1'b0 ),
|
||||
.debug_mode_i ( debug_mode ),
|
||||
|
@ -469,7 +472,8 @@ module ariane #(
|
|||
// CSR
|
||||
// ---------
|
||||
csr_regfile #(
|
||||
.ASID_WIDTH ( ASID_WIDTH )
|
||||
.AsidWidth ( ASID_WIDTH ),
|
||||
.DmBaseAddress ( DmBaseAddress )
|
||||
) csr_regfile_i (
|
||||
.flush_o ( flush_csr_ctrl ),
|
||||
.halt_csr_o ( halt_csr_ctrl ),
|
||||
|
|
|
@ -15,8 +15,9 @@
|
|||
import ariane_pkg::*;
|
||||
|
||||
module csr_regfile #(
|
||||
parameter int ASID_WIDTH = 1,
|
||||
parameter int unsigned NR_COMMIT_PORTS = 2
|
||||
parameter logic [63:0] DmBaseAddress = 64'h0, // debug module base address
|
||||
parameter int AsidWidth = 1,
|
||||
parameter int unsigned NrCommitPorts = 2
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
@ -25,8 +26,8 @@ module csr_regfile #(
|
|||
output logic flush_o,
|
||||
output logic halt_csr_o, // halt requested
|
||||
// commit acknowledge
|
||||
input scoreboard_entry_t [NR_COMMIT_PORTS-1:0] commit_instr_i, // the instruction we want to commit
|
||||
input logic [NR_COMMIT_PORTS-1:0] commit_ack_i, // Commit acknowledged a instruction -> increase instret CSR
|
||||
input scoreboard_entry_t [NrCommitPorts-1:0] commit_instr_i, // the instruction we want to commit
|
||||
input logic [NrCommitPorts-1:0] commit_ack_i, // Commit acknowledged a instruction -> increase instret CSR
|
||||
// Core and Cluster ID
|
||||
input logic [63:0] boot_addr_i, // Address from which to start booting, mtvec is set to the same address
|
||||
input logic [63:0] hart_id_i, // Hart id in a multicore environment (reflected in a CSR)
|
||||
|
@ -60,7 +61,7 @@ module csr_regfile #(
|
|||
output logic sum_o,
|
||||
output logic mxr_o,
|
||||
output logic [43:0] satp_ppn_o,
|
||||
output logic [ASID_WIDTH-1:0] asid_o,
|
||||
output logic [AsidWidth-1:0] asid_o,
|
||||
// external interrupts
|
||||
input logic [1:0] irq_i, // external interrupt in
|
||||
input logic ipi_i, // inter processor interrupt -> connected to machine mode sw
|
||||
|
@ -274,7 +275,7 @@ module csr_regfile #(
|
|||
instret_d = instret_q;
|
||||
if (!debug_mode_q) begin
|
||||
// increase instruction retired counter
|
||||
for (int i = 0; i < NR_COMMIT_PORTS; i++) begin
|
||||
for (int i = 0; i < NrCommitPorts; i++) begin
|
||||
if (commit_ack_i[i] && !ex_i.valid) instret++;
|
||||
end
|
||||
instret_d = instret;
|
||||
|
@ -439,7 +440,7 @@ module csr_regfile #(
|
|||
else begin
|
||||
sapt = riscv::satp_t'(csr_wdata);
|
||||
// only make ASID_LEN - 1 bit stick, that way software can figure out how many ASID bits are supported
|
||||
sapt.asid = sapt.asid & {{(16-ASID_WIDTH){1'b0}}, {ASID_WIDTH{1'b1}}};
|
||||
sapt.asid = sapt.asid & {{(16-AsidWidth){1'b0}}, {AsidWidth{1'b1}}};
|
||||
// only update if we actually support this mode
|
||||
if (sapt.mode == MODE_OFF || sapt.mode == MODE_SV39) satp_d = sapt;
|
||||
end
|
||||
|
@ -906,7 +907,7 @@ module csr_regfile #(
|
|||
|
||||
// if we are in debug mode jump to a specific address
|
||||
if (debug_mode_q) begin
|
||||
trap_vector_base_o = dm::ExceptionAddress;
|
||||
trap_vector_base_o = DmBaseAddress + dm::ExceptionAddress;
|
||||
end
|
||||
|
||||
// check if we are in vectored mode, if yes then do BASE + 4 * cause
|
||||
|
@ -955,7 +956,7 @@ module csr_regfile #(
|
|||
assign fprec_o = fcsr_q.fprec;
|
||||
// MMU outputs
|
||||
assign satp_ppn_o = satp_q.ppn;
|
||||
assign asid_o = satp_q.asid[ASID_WIDTH-1:0];
|
||||
assign asid_o = satp_q.asid[AsidWidth-1:0];
|
||||
assign sum_o = mstatus_q.sum;
|
||||
// we support bare memory addressing and SV39
|
||||
assign en_translation_o = (satp_q.mode == 4'h8 && priv_lvl_o != riscv::PRIV_LVL_M)
|
||||
|
|
|
@ -1,21 +1,28 @@
|
|||
# See LICENSE.SiFive for license details
|
||||
|
||||
debug_rom = debug_rom.img
|
||||
debug_rom = debug_rom.sv
|
||||
|
||||
GCC=riscv64-unknown-elf-gcc
|
||||
OBJCOPY=riscv64-unknown-elf-objcopy
|
||||
OBJDUMP=riscv64-unknown-elf-objdump
|
||||
|
||||
all: $(debug_rom)
|
||||
|
||||
%.sv: %.img
|
||||
python gen_rom.py $<
|
||||
|
||||
%.img: %.bin
|
||||
dd if=$< of=$@ bs=128 count=1
|
||||
dd if=$< of=$@ bs=256 count=1
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
|
||||
%.elf: %.S link.ld
|
||||
$(GCC) -I$(RISCV)/include -Tlink.ld $< -nostdlib -static -Wl,--no-gc-sections -o $@
|
||||
$(GCC) -I$(RISCV)/include -Tlink.ld $< -nostdlib -fPIC -static -Wl,--no-gc-sections -o $@
|
||||
|
||||
%.dump: %.elf
|
||||
$(OBJDUMP) -d $< --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.text.init --section=.data > $@
|
||||
|
||||
clean:
|
||||
rm $(debug_rom)
|
||||
rm -f *.img *.dump *.bin *.sv
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// See LICENSE.SiFive for license details.
|
||||
|
||||
#include "spike/encoding.h"
|
||||
#include "encoding.h"
|
||||
|
||||
// These are implementation-specific addresses in the Debug Module
|
||||
#define HALTED 0x100
|
||||
|
@ -29,11 +29,17 @@ resume:
|
|||
exception:
|
||||
jal zero, _exception
|
||||
|
||||
|
||||
|
||||
_entry:
|
||||
// This fence is required because the execution may have written something
|
||||
// into the Abstract Data or Program Buffer registers.
|
||||
fence
|
||||
csrw CSR_DSCRATCH, s0 // Save s0 to allow signaling MHARTID
|
||||
csrw CSR_DSCRATCH0, s0 // Save s0 to allow signaling MHARTID
|
||||
csrw CSR_DSCRATCH1, a0 // Save a0 to allow loading arbitrary DM base
|
||||
auipc a0, 0 // Get PC
|
||||
srli a0, a0, 12 // And throw away lower 12 bits to get the DM base
|
||||
slli a0, a0, 12
|
||||
|
||||
// We continue to let the hart know that we are halted in order that
|
||||
// a DM which was reset is still made aware that a hart is halted.
|
||||
|
@ -41,28 +47,37 @@ _entry:
|
|||
// us to do, or whether we should resume.
|
||||
entry_loop:
|
||||
csrr s0, CSR_MHARTID
|
||||
sw s0, HALTED(zero)
|
||||
sw s0, HALTED(a0)
|
||||
add s0, s0, a0
|
||||
lbu s0, FLAGS(s0) // 1 byte flag per hart. Only one hart advances here.
|
||||
andi s0, s0, (1 << FLAG_GO)
|
||||
bnez s0, going
|
||||
csrr s0, CSR_MHARTID
|
||||
add s0, s0, a0
|
||||
lbu s0, FLAGS(s0) // multiple harts can resume here
|
||||
andi s0, s0, (1 << FLAG_RESUME)
|
||||
bnez s0, resume
|
||||
jal zero, entry_loop
|
||||
|
||||
_exception:
|
||||
sw zero, EXCEPTION(zero) // Let debug module know you got an exception.
|
||||
csrw CSR_DSCRATCH1, a0 // Save a0 to allow loading arbitrary DM offsets
|
||||
auipc a0, 0 // Get POC
|
||||
srli a0, a0, 12 // And throw away lower 12 bits to get the DM base
|
||||
slli a0, a0, 12
|
||||
sw zero, EXCEPTION(a0) // Let debug module know you got an exception.
|
||||
csrr a0, CSR_DSCRATCH1 // Restore a0 here
|
||||
ebreak
|
||||
|
||||
going:
|
||||
csrr s0, CSR_DSCRATCH // Restore s0 here
|
||||
sw zero, GOING(zero) // When debug module sees this write, the GO flag is reset.
|
||||
jalr zero, zero, %lo(whereto)
|
||||
sw zero, GOING(a0) // When debug module sees this write, the GO flag is reset.
|
||||
csrr s0, CSR_DSCRATCH0 // Restore s0 here
|
||||
csrr a0, CSR_DSCRATCH1 // Restore a0 here
|
||||
jal zero, whereto
|
||||
_resume:
|
||||
csrr s0, CSR_MHARTID
|
||||
sw s0, RESUMING(zero) // When Debug Module sees this write, the RESUME flag is reset.
|
||||
csrr s0, CSR_DSCRATCH // Restore s0
|
||||
sw s0, RESUMING(a0) // When Debug Module sees this write, the RESUME flag is reset.
|
||||
csrr s0, CSR_DSCRATCH0 // Restore s0 here
|
||||
csrr a0, CSR_DSCRATCH1 // Restore a0 here
|
||||
dret
|
||||
|
||||
// END OF ACTUAL "ROM" CONTENTS. BELOW IS JUST FOR LINKER SCRIPT.
|
||||
|
|
|
@ -20,22 +20,28 @@ module debug_rom (
|
|||
input logic [63:0] addr_i,
|
||||
output logic [63:0] rdata_o
|
||||
);
|
||||
localparam int RomSize = 13;
|
||||
localparam int RomSize = 19;
|
||||
|
||||
const logic [RomSize-1:0][63:0] mem = {
|
||||
64'h00000000_00000000,
|
||||
64'h7B200073_7B202473,
|
||||
64'h10802423_F1402473,
|
||||
64'h30000067_10002223,
|
||||
64'h7B202473_00100073,
|
||||
64'h10002623_FDDFF06F,
|
||||
64'hFC0418E3_00247413,
|
||||
64'h40044403_F1402473,
|
||||
64'h02041063_00147413,
|
||||
64'h40044403_10802023,
|
||||
64'hF1402473_7B241073,
|
||||
64'h0FF0000F_0340006F,
|
||||
64'h04C0006F_00C0006F
|
||||
64'h00000000_7b200073,
|
||||
64'h7b302573_7b202473,
|
||||
64'h10852423_f1402473,
|
||||
64'ha85ff06f_7b302573,
|
||||
64'h7b202473_10052223,
|
||||
64'h00100073_7b302573,
|
||||
64'h10052623_00c51513,
|
||||
64'h00c55513_00000517,
|
||||
64'h7b351073_fd5ff06f,
|
||||
64'hfa041ce3_00247413,
|
||||
64'h40044403_00a40433,
|
||||
64'hf1402473_02041c63,
|
||||
64'h00147413_40044403,
|
||||
64'h00a40433_10852023,
|
||||
64'hf1402473_00c51513,
|
||||
64'h00c55513_00000517,
|
||||
64'h7b351073_7b241073,
|
||||
64'h0ff0000f_04c0006f,
|
||||
64'h07c0006f_00c0006f
|
||||
};
|
||||
|
||||
logic [$clog2(RomSize)-1:0] addr_q;
|
||||
|
@ -46,7 +52,7 @@ module debug_rom (
|
|||
end
|
||||
end
|
||||
|
||||
// this prevents spurious Xes from propagating into
|
||||
// this prevents spurious Xes from propagating into
|
||||
// the speculative fetch stage of the core
|
||||
assign rdata_o = (addr_q<RomSize) ? mem[addr_q] : '0;
|
||||
assign rdata_o = (addr_q < RomSize) ? mem[addr_q] : '0;
|
||||
endmodule
|
||||
|
|
|
@ -60,11 +60,11 @@ module dm_mem #(
|
|||
localparam logic [DbgAddressBits-1:0] DataEnd = (dm::DataAddr + 4*dm::DataCount);
|
||||
localparam logic [DbgAddressBits-1:0] ProgBufBase = (dm::DataAddr - 4*dm::ProgBufSize);
|
||||
localparam logic [DbgAddressBits-1:0] ProgBufEnd = (dm::DataAddr - 1);
|
||||
localparam logic [DbgAddressBits-1:0] AbstractCmdBase = (ProgBufBase - 4*6);
|
||||
localparam logic [DbgAddressBits-1:0] AbstractCmdBase = (ProgBufBase - 4*10);
|
||||
localparam logic [DbgAddressBits-1:0] AbstractCmdEnd = (ProgBufBase - 1);
|
||||
localparam logic [DbgAddressBits-1:0] WhereTo = 'h300;
|
||||
localparam logic [DbgAddressBits-1:0] FlagsBase = 'h400;
|
||||
localparam logic [DbgAddressBits-1:0] FlagsEnd = 'h7FF;
|
||||
localparam logic [DbgAddressBits-1:0] WhereTo = 'h300;
|
||||
localparam logic [DbgAddressBits-1:0] FlagsBase = 'h400;
|
||||
localparam logic [DbgAddressBits-1:0] FlagsEnd = 'h7FF;
|
||||
|
||||
|
||||
localparam logic [DbgAddressBits-1:0] Halted = 'h100;
|
||||
|
@ -72,7 +72,8 @@ module dm_mem #(
|
|||
localparam logic [DbgAddressBits-1:0] Resuming = 'h108;
|
||||
localparam logic [DbgAddressBits-1:0] Exception = 'h10C;
|
||||
|
||||
logic [2:0][63:0] abstract_cmd;
|
||||
logic [dm::ProgBufSize/2-1:0][63:0] progbuf;
|
||||
logic [4:0][63:0] abstract_cmd;
|
||||
logic [NrHarts-1:0] halted_d, halted_q;
|
||||
logic [NrHarts-1:0] resuming_d, resuming_q;
|
||||
logic resume, go, going;
|
||||
|
@ -95,6 +96,9 @@ module dm_mem #(
|
|||
assign halted_o = halted_q;
|
||||
assign resuming_o = resuming_q;
|
||||
|
||||
// reshape progbuf
|
||||
assign progbuf = progbuf_i;
|
||||
|
||||
enum logic [1:0] { Idle, Go, Resume, CmdExecuting } state_d, state_q;
|
||||
|
||||
// hart ctrl queue
|
||||
|
@ -218,17 +222,17 @@ module dm_mem #(
|
|||
WhereTo: begin
|
||||
// variable jump to abstract cmd, program_buffer or resume
|
||||
if (resumereq_i) begin
|
||||
rdata_d = {32'b0, riscv::jalr(0, 0, dm::ResumeAddress[11:0])};
|
||||
rdata_d = {32'b0, riscv::jal(0, dm::ResumeAddress[11:0]-WhereTo)};
|
||||
end
|
||||
|
||||
// there is a command active so jump there
|
||||
if (cmdbusy_o) begin
|
||||
// transfer not set is a shortcut to the program buffer
|
||||
if (!ac_ar.transfer) begin
|
||||
rdata_d = {32'b0, riscv::jalr(0, 0, ProgBufBase)};
|
||||
rdata_d = {32'b0, riscv::jal(0, ProgBufBase-WhereTo)};
|
||||
// this is a legit abstract cmd -> execute it
|
||||
end else begin
|
||||
rdata_d = {32'b0, riscv::jalr(0, 0, AbstractCmdBase)};
|
||||
rdata_d = {32'b0, riscv::jal(0, AbstractCmdBase-WhereTo)};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -238,13 +242,8 @@ module dm_mem #(
|
|||
rdata_d = {data_i[1], data_i[0]};
|
||||
end
|
||||
|
||||
// TODO(zarubaf) change hard-coded values
|
||||
[ProgBufBase:ProgBufEnd]: begin
|
||||
case (addr_i[DbgAddressBits-1:0])
|
||||
ProgBufBase + 16: rdata_d = {progbuf_i[5], progbuf_i[4]};
|
||||
ProgBufBase + 8: rdata_d = {progbuf_i[3], progbuf_i[2]};
|
||||
ProgBufBase: rdata_d = {progbuf_i[1], progbuf_i[0]};
|
||||
endcase
|
||||
rdata_d = progbuf[(addr_i[DbgAddressBits-1:3] - ProgBufBase[DbgAddressBits-1:3])];
|
||||
end
|
||||
|
||||
// two slots for abstract command
|
||||
|
@ -276,11 +275,16 @@ module dm_mem #(
|
|||
// default memory
|
||||
// if ac_ar.transfer is not set then we can take a shortcut to the program buffer
|
||||
abstract_cmd[0][31:0] = riscv::illegal();
|
||||
abstract_cmd[0][63:32] = riscv::nop();
|
||||
abstract_cmd[1][31:0] = riscv::nop();
|
||||
abstract_cmd[1][63:32] = riscv::nop();
|
||||
// load debug module base address into a0, this is shared among all commands
|
||||
abstract_cmd[0][63:32] = riscv::auipc(10, 0);
|
||||
abstract_cmd[1][31:0] = riscv::srli(10, 10, 12); // clear lowest 12bit to get base offset of DM
|
||||
abstract_cmd[1][63:32] = riscv::slli(10, 10, 12);
|
||||
abstract_cmd[2][31:0] = riscv::nop();
|
||||
abstract_cmd[2][63:32] = riscv::ebreak();
|
||||
abstract_cmd[2][63:32] = riscv::nop();
|
||||
abstract_cmd[3][31:0] = riscv::nop();
|
||||
abstract_cmd[3][63:32] = riscv::nop();
|
||||
abstract_cmd[4][31:0] = riscv::csrr(riscv::CSR_DSCRATCH1, 10);
|
||||
abstract_cmd[4][63:32] = riscv::ebreak();
|
||||
|
||||
// this depends on the command being executed
|
||||
unique case (cmd_i.cmdtype)
|
||||
|
@ -289,6 +293,8 @@ module dm_mem #(
|
|||
// --------------------
|
||||
dm::AccessRegister: begin
|
||||
if (ac_ar.aarsize < 4 && ac_ar.transfer && ac_ar.write) begin
|
||||
// store a0 in dscratch1
|
||||
abstract_cmd[0][31:0] = riscv::csrw(riscv::CSR_DSCRATCH1, 10);
|
||||
// this range is reserved
|
||||
if (ac_ar.regno[15:14] != '0) begin
|
||||
abstract_cmd[0][31:0] = riscv::illegal();
|
||||
|
@ -296,23 +302,25 @@ module dm_mem #(
|
|||
end else if (ac_ar.regno[12]) begin
|
||||
// determine whether we want to access the floating point register or not
|
||||
if (ac_ar.regno[5]) begin
|
||||
abstract_cmd[0][31:0] = riscv::float_load(ac_ar.aarsize, ac_ar.regno[4:0], 0, dm::DataAddr);
|
||||
abstract_cmd[2][31:0] = riscv::float_load(ac_ar.aarsize, ac_ar.regno[4:0], 10, dm::DataAddr);
|
||||
end else begin
|
||||
abstract_cmd[0][31:0] = riscv::load(ac_ar.aarsize, ac_ar.regno[4:0], 0, dm::DataAddr);
|
||||
abstract_cmd[2][31:0] = riscv::load(ac_ar.aarsize, ac_ar.regno[4:0], 10, dm::DataAddr);
|
||||
end
|
||||
// CSR access
|
||||
end else begin
|
||||
// data register to CSR
|
||||
// store s0 in dscratch
|
||||
abstract_cmd[0][31:0] = riscv::csrw(riscv::CSR_DSCRATCH0, 8);
|
||||
abstract_cmd[2][31:0] = riscv::csrw(riscv::CSR_DSCRATCH0, 8);
|
||||
// load from data register
|
||||
abstract_cmd[0][63:32] = riscv::load(ac_ar.aarsize, 8, 0, dm::DataAddr);
|
||||
abstract_cmd[2][63:32] = riscv::load(ac_ar.aarsize, 8, 10, dm::DataAddr);
|
||||
// and store it in the corresponding CSR
|
||||
abstract_cmd[1][31:0] = riscv::csrw(riscv::csr_reg_t'(ac_ar.regno[11:0]), 8);
|
||||
abstract_cmd[3][31:0] = riscv::csrw(riscv::csr_reg_t'(ac_ar.regno[11:0]), 8);
|
||||
// restore s0 again from dscratch
|
||||
abstract_cmd[1][63:32] = riscv::csrr(riscv::CSR_DSCRATCH0, 8);
|
||||
abstract_cmd[3][63:32] = riscv::csrr(riscv::CSR_DSCRATCH0, 8);
|
||||
end
|
||||
end else if (ac_ar.aarsize < 4 && ac_ar.transfer && !ac_ar.write) begin
|
||||
// store a0 in dscratch1
|
||||
abstract_cmd[0][31:0] = riscv::csrw(riscv::CSR_DSCRATCH1, 10);
|
||||
// this range is reserved
|
||||
if (ac_ar.regno[15:14] != '0) begin
|
||||
abstract_cmd[0][31:0] = riscv::illegal();
|
||||
|
@ -320,28 +328,28 @@ module dm_mem #(
|
|||
end else if (ac_ar.regno[12]) begin
|
||||
// determine whether we want to access the floating point register or not
|
||||
if (ac_ar.regno[5]) begin
|
||||
abstract_cmd[0][31:0] = riscv::float_store(ac_ar.aarsize, ac_ar.regno[4:0], 0, dm::DataAddr);
|
||||
abstract_cmd[2][31:0] = riscv::float_store(ac_ar.aarsize, ac_ar.regno[4:0], 10, dm::DataAddr);
|
||||
end else begin
|
||||
abstract_cmd[0][31:0] = riscv::store(ac_ar.aarsize, ac_ar.regno[4:0], 0, dm::DataAddr);
|
||||
abstract_cmd[2][31:0] = riscv::store(ac_ar.aarsize, ac_ar.regno[4:0], 10, dm::DataAddr);
|
||||
end
|
||||
// CSR access
|
||||
end else begin
|
||||
// CSR register to data
|
||||
// store s0 in dscratch
|
||||
abstract_cmd[0][31:0] = riscv::csrw(riscv::CSR_DSCRATCH0, 8);
|
||||
abstract_cmd[2][31:0] = riscv::csrw(riscv::CSR_DSCRATCH0, 8);
|
||||
// read value from CSR into s0
|
||||
abstract_cmd[0][63:32] = riscv::csrr(riscv::csr_reg_t'(ac_ar.regno[11:0]), 8);
|
||||
abstract_cmd[2][63:32] = riscv::csrr(riscv::csr_reg_t'(ac_ar.regno[11:0]), 8);
|
||||
// and store s0 into data section
|
||||
abstract_cmd[1][31:0] = riscv::store(ac_ar.aarsize, 8, 0, dm::DataAddr);
|
||||
abstract_cmd[3][31:0] = riscv::store(ac_ar.aarsize, 8, 10, dm::DataAddr);
|
||||
// restore s0 again from dscratch
|
||||
abstract_cmd[1][63:32] = riscv::csrr(riscv::CSR_DSCRATCH0, 8);
|
||||
abstract_cmd[3][63:32] = riscv::csrr(riscv::CSR_DSCRATCH0, 8);
|
||||
end
|
||||
end
|
||||
|
||||
// check whether we need to execute the program buffer
|
||||
if (ac_ar.postexec) begin
|
||||
// issue a nop, we will automatically run into the program buffer
|
||||
abstract_cmd[2][63:32] = riscv::nop();
|
||||
abstract_cmd[4][63:32] = riscv::nop();
|
||||
end
|
||||
end
|
||||
// not supported at the moment
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
package dm;
|
||||
localparam logic [3:0] DbgVersion013 = 4'h2;
|
||||
// size of program buffer in junks of 32-bit words
|
||||
localparam logic [4:0] ProgBufSize = 5'h6;
|
||||
localparam logic [4:0] ProgBufSize = 5'h8;
|
||||
|
||||
// TODO(zarubaf) This is hard-coded to two at the moment
|
||||
// amount of data count registers implemented
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
|
||||
import ariane_pkg::*;
|
||||
|
||||
module frontend (
|
||||
module frontend #(
|
||||
parameter logic [63:0] DmBaseAddress = 64'h0 // debug module base address
|
||||
) (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic flush_i, // flush request for PCGEN
|
||||
|
@ -357,7 +359,7 @@ module frontend (
|
|||
// -------------------------------
|
||||
// enter debug on a hard-coded base-address
|
||||
if (set_debug_pc_i) begin
|
||||
npc_d = dm::HaltAddress;
|
||||
npc_d = DmBaseAddress + dm::HaltAddress;
|
||||
end
|
||||
|
||||
icache_dreq_o.vaddr = fetch_address;
|
||||
|
|
|
@ -18,7 +18,7 @@ package ariane_soc;
|
|||
localparam PLICIdWidth = 3;
|
||||
localparam ParameterBitwidth = PLICIdWidth;
|
||||
|
||||
typedef enum int unsigned {
|
||||
typedef enum int unsigned {
|
||||
DRAM = 0,
|
||||
GPIO = 1,
|
||||
Ethernet = 2,
|
||||
|
|
|
@ -545,7 +545,8 @@ module ariane_testharness #(
|
|||
.SwapEndianess ( 0 ),
|
||||
.CachedAddrEnd ( (ariane_soc::DRAMBase + ariane_soc::DRAMLength) ),
|
||||
`endif
|
||||
.CachedAddrBeg ( ariane_soc::DRAMBase )
|
||||
.CachedAddrBeg ( ariane_soc::DRAMBase ),
|
||||
.DmBaseAddress ( ariane_soc::DebugBase )
|
||||
) i_ariane (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( ndmreset_n ),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue