picorv32 now runs: debugging outputs
This commit is contained in:
parent
67c670cb5c
commit
f5b14d51ab
|
@ -49,7 +49,7 @@ hardware-get:
|
||||||
docker cp upsilon-hardware:/home/user/upsilon/gateware/build/digilent_arty/gateware/digilent_arty.bit ../boot/
|
docker cp upsilon-hardware:/home/user/upsilon/gateware/build/digilent_arty/gateware/digilent_arty.bit ../boot/
|
||||||
docker cp upsilon-hardware:/home/user/upsilon/gateware/arty.dtb ../boot/
|
docker cp upsilon-hardware:/home/user/upsilon/gateware/arty.dtb ../boot/
|
||||||
docker cp upsilon-hardware:/home/user/upsilon/gateware/csr.json ../boot/
|
docker cp upsilon-hardware:/home/user/upsilon/gateware/csr.json ../boot/
|
||||||
docker cp upsilon-hardware:/home/user/upsilon/gateware/picorv32.json ../boot/
|
docker cp upsilon-hardware:/home/user/upsilon/gateware/pico0.json ../boot/
|
||||||
docker cp upsilon-hardware:/home/user/upsilon/gateware/mmio.py ../boot/
|
docker cp upsilon-hardware:/home/user/upsilon/gateware/mmio.py ../boot/
|
||||||
hardware-clean:
|
hardware-clean:
|
||||||
-docker container stop upsilon-hardware
|
-docker container stop upsilon-hardware
|
||||||
|
|
|
@ -22,7 +22,7 @@ with open(sys.argv[1], 'rt') as f:
|
||||||
print("from micropython import const")
|
print("from micropython import const")
|
||||||
|
|
||||||
for key in j["csr_registers"]:
|
for key in j["csr_registers"]:
|
||||||
if key.startswith("picorv32"):
|
if key.startswith("pico0"):
|
||||||
print(f'{key} = const({j["csr_registers"][key]["addr"]})')
|
print(f'{key} = const({j["csr_registers"][key]["addr"]})')
|
||||||
|
|
||||||
print(f'picorv32_ram = const({j["memories"]["picorv32_ram"]["base"]})')
|
print(f'pico0_ram = const({j["memories"]["pico0_ram"]["base"]})')
|
||||||
|
|
|
@ -90,7 +90,6 @@ module picorv32 #(
|
||||||
parameter [31:0] STACKADDR = 32'h ffff_ffff
|
parameter [31:0] STACKADDR = 32'h ffff_ffff
|
||||||
) (
|
) (
|
||||||
input clk, resetn,
|
input clk, resetn,
|
||||||
output reg trap,
|
|
||||||
|
|
||||||
output reg mem_valid,
|
output reg mem_valid,
|
||||||
output reg mem_instr,
|
output reg mem_instr,
|
||||||
|
@ -156,10 +155,24 @@ module picorv32 #(
|
||||||
output reg [63:0] rvfi_csr_minstret_wdata,
|
output reg [63:0] rvfi_csr_minstret_wdata,
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
/* Debugging interface */
|
||||||
|
`define TRAP_RS1_ILLINSN 7'd1
|
||||||
|
`define TRAP_RS2_ILLINSN 7'd2
|
||||||
|
`define TRAP_MAL_WORD 7'd3
|
||||||
|
`define TRAP_MAL_HWORD 7'd4
|
||||||
|
`define TRAP_MAL_INS 7'd5
|
||||||
|
`define TRAP_EBREAK 7'd6
|
||||||
|
output reg [7:0] trap,
|
||||||
|
output reg [31:0] dbg_insn_addr,
|
||||||
|
output reg [31:0] dbg_insn_opcode,
|
||||||
|
|
||||||
// Trace Interface
|
// Trace Interface
|
||||||
output reg trace_valid,
|
output reg trace_valid,
|
||||||
output reg [35:0] trace_data
|
output reg [35:0] trace_data
|
||||||
);
|
);
|
||||||
|
|
||||||
|
reg [7:0] trap_type;
|
||||||
|
|
||||||
localparam integer irq_timer = 0;
|
localparam integer irq_timer = 0;
|
||||||
localparam integer irq_ebreak = 1;
|
localparam integer irq_ebreak = 1;
|
||||||
localparam integer irq_buserror = 2;
|
localparam integer irq_buserror = 2;
|
||||||
|
@ -179,8 +192,6 @@ module picorv32 #(
|
||||||
reg [4:0] reg_sh;
|
reg [4:0] reg_sh;
|
||||||
|
|
||||||
reg [31:0] next_insn_opcode;
|
reg [31:0] next_insn_opcode;
|
||||||
reg [31:0] dbg_insn_opcode;
|
|
||||||
reg [31:0] dbg_insn_addr;
|
|
||||||
|
|
||||||
wire dbg_mem_valid = mem_valid;
|
wire dbg_mem_valid = mem_valid;
|
||||||
wire dbg_mem_instr = mem_instr;
|
wire dbg_mem_instr = mem_instr;
|
||||||
|
@ -1486,7 +1497,7 @@ module picorv32 #(
|
||||||
(* parallel_case, full_case *)
|
(* parallel_case, full_case *)
|
||||||
case (cpu_state)
|
case (cpu_state)
|
||||||
cpu_state_trap: begin
|
cpu_state_trap: begin
|
||||||
trap <= 1;
|
trap <= trap_type;
|
||||||
end
|
end
|
||||||
|
|
||||||
cpu_state_fetch: begin
|
cpu_state_fetch: begin
|
||||||
|
@ -1609,9 +1620,11 @@ module picorv32 #(
|
||||||
if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin
|
if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin
|
||||||
next_irq_pending[irq_ebreak] = 1;
|
next_irq_pending[irq_ebreak] = 1;
|
||||||
cpu_state <= cpu_state_fetch;
|
cpu_state <= cpu_state_fetch;
|
||||||
end else
|
end else begin
|
||||||
|
trap_type <= `TRAP_RS1_ILLINSN;
|
||||||
cpu_state <= cpu_state_trap;
|
cpu_state <= cpu_state_trap;
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end else begin
|
end else begin
|
||||||
cpu_state <= cpu_state_ld_rs2;
|
cpu_state <= cpu_state_ld_rs2;
|
||||||
end
|
end
|
||||||
|
@ -1620,10 +1633,12 @@ module picorv32 #(
|
||||||
if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin
|
if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin
|
||||||
next_irq_pending[irq_ebreak] = 1;
|
next_irq_pending[irq_ebreak] = 1;
|
||||||
cpu_state <= cpu_state_fetch;
|
cpu_state <= cpu_state_fetch;
|
||||||
end else
|
end else begin
|
||||||
|
trap_type <= `TRAP_RS1_ILLINSN;
|
||||||
cpu_state <= cpu_state_trap;
|
cpu_state <= cpu_state_trap;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
ENABLE_COUNTERS && is_rdcycle_rdcycleh_rdinstr_rdinstrh: begin
|
ENABLE_COUNTERS && is_rdcycle_rdcycleh_rdinstr_rdinstrh: begin
|
||||||
(* parallel_case, full_case *)
|
(* parallel_case, full_case *)
|
||||||
case (1'b1)
|
case (1'b1)
|
||||||
|
@ -1781,10 +1796,12 @@ module picorv32 #(
|
||||||
if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin
|
if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin
|
||||||
next_irq_pending[irq_ebreak] = 1;
|
next_irq_pending[irq_ebreak] = 1;
|
||||||
cpu_state <= cpu_state_fetch;
|
cpu_state <= cpu_state_fetch;
|
||||||
end else
|
end else begin
|
||||||
|
trap_type <= `TRAP_RS2_ILLINSN;
|
||||||
cpu_state <= cpu_state_trap;
|
cpu_state <= cpu_state_trap;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
is_sb_sh_sw: begin
|
is_sb_sh_sw: begin
|
||||||
cpu_state <= cpu_state_stmem;
|
cpu_state <= cpu_state_stmem;
|
||||||
mem_do_rinst <= 1;
|
mem_do_rinst <= 1;
|
||||||
|
@ -1925,25 +1942,32 @@ module picorv32 #(
|
||||||
`debug($display("MISALIGNED WORD: 0x%08x", reg_op1);)
|
`debug($display("MISALIGNED WORD: 0x%08x", reg_op1);)
|
||||||
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
|
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
|
||||||
next_irq_pending[irq_buserror] = 1;
|
next_irq_pending[irq_buserror] = 1;
|
||||||
end else
|
end else begin
|
||||||
|
trap_type <= `TRAP_MAL_WORD;
|
||||||
cpu_state <= cpu_state_trap;
|
cpu_state <= cpu_state_trap;
|
||||||
end
|
end
|
||||||
|
end
|
||||||
if (mem_wordsize == 1 && reg_op1[0] != 0) begin
|
if (mem_wordsize == 1 && reg_op1[0] != 0) begin
|
||||||
`debug($display("MISALIGNED HALFWORD: 0x%08x", reg_op1);)
|
`debug($display("MISALIGNED HALFWORD: 0x%08x", reg_op1);)
|
||||||
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
|
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
|
||||||
next_irq_pending[irq_buserror] = 1;
|
next_irq_pending[irq_buserror] = 1;
|
||||||
end else
|
end else begin
|
||||||
|
trap_type <= `TRAP_MAL_HWORD;
|
||||||
cpu_state <= cpu_state_trap;
|
cpu_state <= cpu_state_trap;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
if (CATCH_MISALIGN && resetn && mem_do_rinst && (COMPRESSED_ISA ? reg_pc[0] : |reg_pc[1:0])) begin
|
if (CATCH_MISALIGN && resetn && mem_do_rinst && (COMPRESSED_ISA ? reg_pc[0] : |reg_pc[1:0])) begin
|
||||||
`debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);)
|
`debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);)
|
||||||
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
|
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
|
||||||
next_irq_pending[irq_buserror] = 1;
|
next_irq_pending[irq_buserror] = 1;
|
||||||
end else
|
end else begin
|
||||||
|
trap_type <= `TRAP_MAL_INS;
|
||||||
cpu_state <= cpu_state_trap;
|
cpu_state <= cpu_state_trap;
|
||||||
end
|
end
|
||||||
|
end
|
||||||
if (!CATCH_ILLINSN && decoder_trigger_q && !decoder_pseudo_trigger_q && instr_ecall_ebreak) begin
|
if (!CATCH_ILLINSN && decoder_trigger_q && !decoder_pseudo_trigger_q && instr_ecall_ebreak) begin
|
||||||
|
trap_type <= `TRAP_EBREAK;
|
||||||
cpu_state <= cpu_state_trap;
|
cpu_state <= cpu_state_trap;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -2510,302 +2534,6 @@ module picorv32_pcpi_div (
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* picorv32_axi
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
module picorv32_axi #(
|
|
||||||
parameter [ 0:0] ENABLE_COUNTERS = 1,
|
|
||||||
parameter [ 0:0] ENABLE_COUNTERS64 = 1,
|
|
||||||
parameter [ 0:0] ENABLE_REGS_16_31 = 1,
|
|
||||||
parameter [ 0:0] ENABLE_REGS_DUALPORT = 1,
|
|
||||||
parameter [ 0:0] TWO_STAGE_SHIFT = 1,
|
|
||||||
parameter [ 0:0] BARREL_SHIFTER = 0,
|
|
||||||
parameter [ 0:0] TWO_CYCLE_COMPARE = 0,
|
|
||||||
parameter [ 0:0] TWO_CYCLE_ALU = 0,
|
|
||||||
parameter [ 0:0] COMPRESSED_ISA = 0,
|
|
||||||
parameter [ 0:0] CATCH_MISALIGN = 1,
|
|
||||||
parameter [ 0:0] CATCH_ILLINSN = 1,
|
|
||||||
parameter [ 0:0] ENABLE_PCPI = 0,
|
|
||||||
parameter [ 0:0] ENABLE_MUL = 0,
|
|
||||||
parameter [ 0:0] ENABLE_FAST_MUL = 0,
|
|
||||||
parameter [ 0:0] ENABLE_DIV = 0,
|
|
||||||
parameter [ 0:0] ENABLE_IRQ = 0,
|
|
||||||
parameter [ 0:0] ENABLE_IRQ_QREGS = 1,
|
|
||||||
parameter [ 0:0] ENABLE_IRQ_TIMER = 1,
|
|
||||||
parameter [ 0:0] ENABLE_TRACE = 0,
|
|
||||||
parameter [ 0:0] REGS_INIT_ZERO = 0,
|
|
||||||
parameter [31:0] MASKED_IRQ = 32'h 0000_0000,
|
|
||||||
parameter [31:0] LATCHED_IRQ = 32'h ffff_ffff,
|
|
||||||
parameter [31:0] PROGADDR_RESET = 32'h 0000_0000,
|
|
||||||
parameter [31:0] PROGADDR_IRQ = 32'h 0000_0010,
|
|
||||||
parameter [31:0] STACKADDR = 32'h ffff_ffff
|
|
||||||
) (
|
|
||||||
input clk, resetn,
|
|
||||||
output trap,
|
|
||||||
|
|
||||||
// AXI4-lite master memory interface
|
|
||||||
|
|
||||||
output mem_axi_awvalid,
|
|
||||||
input mem_axi_awready,
|
|
||||||
output [31:0] mem_axi_awaddr,
|
|
||||||
output [ 2:0] mem_axi_awprot,
|
|
||||||
|
|
||||||
output mem_axi_wvalid,
|
|
||||||
input mem_axi_wready,
|
|
||||||
output [31:0] mem_axi_wdata,
|
|
||||||
output [ 3:0] mem_axi_wstrb,
|
|
||||||
|
|
||||||
input mem_axi_bvalid,
|
|
||||||
output mem_axi_bready,
|
|
||||||
|
|
||||||
output mem_axi_arvalid,
|
|
||||||
input mem_axi_arready,
|
|
||||||
output [31:0] mem_axi_araddr,
|
|
||||||
output [ 2:0] mem_axi_arprot,
|
|
||||||
|
|
||||||
input mem_axi_rvalid,
|
|
||||||
output mem_axi_rready,
|
|
||||||
input [31:0] mem_axi_rdata,
|
|
||||||
|
|
||||||
// Pico Co-Processor Interface (PCPI)
|
|
||||||
output pcpi_valid,
|
|
||||||
output [31:0] pcpi_insn,
|
|
||||||
output [31:0] pcpi_rs1,
|
|
||||||
output [31:0] pcpi_rs2,
|
|
||||||
input pcpi_wr,
|
|
||||||
input [31:0] pcpi_rd,
|
|
||||||
input pcpi_wait,
|
|
||||||
input pcpi_ready,
|
|
||||||
|
|
||||||
// IRQ interface
|
|
||||||
input [31:0] irq,
|
|
||||||
output [31:0] eoi,
|
|
||||||
|
|
||||||
`ifdef RISCV_FORMAL
|
|
||||||
output rvfi_valid,
|
|
||||||
output [63:0] rvfi_order,
|
|
||||||
output [31:0] rvfi_insn,
|
|
||||||
output rvfi_trap,
|
|
||||||
output rvfi_halt,
|
|
||||||
output rvfi_intr,
|
|
||||||
output [ 4:0] rvfi_rs1_addr,
|
|
||||||
output [ 4:0] rvfi_rs2_addr,
|
|
||||||
output [31:0] rvfi_rs1_rdata,
|
|
||||||
output [31:0] rvfi_rs2_rdata,
|
|
||||||
output [ 4:0] rvfi_rd_addr,
|
|
||||||
output [31:0] rvfi_rd_wdata,
|
|
||||||
output [31:0] rvfi_pc_rdata,
|
|
||||||
output [31:0] rvfi_pc_wdata,
|
|
||||||
output [31:0] rvfi_mem_addr,
|
|
||||||
output [ 3:0] rvfi_mem_rmask,
|
|
||||||
output [ 3:0] rvfi_mem_wmask,
|
|
||||||
output [31:0] rvfi_mem_rdata,
|
|
||||||
output [31:0] rvfi_mem_wdata,
|
|
||||||
`endif
|
|
||||||
|
|
||||||
// Trace Interface
|
|
||||||
output trace_valid,
|
|
||||||
output [35:0] trace_data
|
|
||||||
);
|
|
||||||
wire mem_valid;
|
|
||||||
wire [31:0] mem_addr;
|
|
||||||
wire [31:0] mem_wdata;
|
|
||||||
wire [ 3:0] mem_wstrb;
|
|
||||||
wire mem_instr;
|
|
||||||
wire mem_ready;
|
|
||||||
wire [31:0] mem_rdata;
|
|
||||||
|
|
||||||
picorv32_axi_adapter axi_adapter (
|
|
||||||
.clk (clk ),
|
|
||||||
.resetn (resetn ),
|
|
||||||
.mem_axi_awvalid(mem_axi_awvalid),
|
|
||||||
.mem_axi_awready(mem_axi_awready),
|
|
||||||
.mem_axi_awaddr (mem_axi_awaddr ),
|
|
||||||
.mem_axi_awprot (mem_axi_awprot ),
|
|
||||||
.mem_axi_wvalid (mem_axi_wvalid ),
|
|
||||||
.mem_axi_wready (mem_axi_wready ),
|
|
||||||
.mem_axi_wdata (mem_axi_wdata ),
|
|
||||||
.mem_axi_wstrb (mem_axi_wstrb ),
|
|
||||||
.mem_axi_bvalid (mem_axi_bvalid ),
|
|
||||||
.mem_axi_bready (mem_axi_bready ),
|
|
||||||
.mem_axi_arvalid(mem_axi_arvalid),
|
|
||||||
.mem_axi_arready(mem_axi_arready),
|
|
||||||
.mem_axi_araddr (mem_axi_araddr ),
|
|
||||||
.mem_axi_arprot (mem_axi_arprot ),
|
|
||||||
.mem_axi_rvalid (mem_axi_rvalid ),
|
|
||||||
.mem_axi_rready (mem_axi_rready ),
|
|
||||||
.mem_axi_rdata (mem_axi_rdata ),
|
|
||||||
.mem_valid (mem_valid ),
|
|
||||||
.mem_instr (mem_instr ),
|
|
||||||
.mem_ready (mem_ready ),
|
|
||||||
.mem_addr (mem_addr ),
|
|
||||||
.mem_wdata (mem_wdata ),
|
|
||||||
.mem_wstrb (mem_wstrb ),
|
|
||||||
.mem_rdata (mem_rdata )
|
|
||||||
);
|
|
||||||
|
|
||||||
picorv32 #(
|
|
||||||
.ENABLE_COUNTERS (ENABLE_COUNTERS ),
|
|
||||||
.ENABLE_COUNTERS64 (ENABLE_COUNTERS64 ),
|
|
||||||
.ENABLE_REGS_16_31 (ENABLE_REGS_16_31 ),
|
|
||||||
.ENABLE_REGS_DUALPORT(ENABLE_REGS_DUALPORT),
|
|
||||||
.TWO_STAGE_SHIFT (TWO_STAGE_SHIFT ),
|
|
||||||
.BARREL_SHIFTER (BARREL_SHIFTER ),
|
|
||||||
.TWO_CYCLE_COMPARE (TWO_CYCLE_COMPARE ),
|
|
||||||
.TWO_CYCLE_ALU (TWO_CYCLE_ALU ),
|
|
||||||
.COMPRESSED_ISA (COMPRESSED_ISA ),
|
|
||||||
.CATCH_MISALIGN (CATCH_MISALIGN ),
|
|
||||||
.CATCH_ILLINSN (CATCH_ILLINSN ),
|
|
||||||
.ENABLE_PCPI (ENABLE_PCPI ),
|
|
||||||
.ENABLE_MUL (ENABLE_MUL ),
|
|
||||||
.ENABLE_FAST_MUL (ENABLE_FAST_MUL ),
|
|
||||||
.ENABLE_DIV (ENABLE_DIV ),
|
|
||||||
.ENABLE_IRQ (ENABLE_IRQ ),
|
|
||||||
.ENABLE_IRQ_QREGS (ENABLE_IRQ_QREGS ),
|
|
||||||
.ENABLE_IRQ_TIMER (ENABLE_IRQ_TIMER ),
|
|
||||||
.ENABLE_TRACE (ENABLE_TRACE ),
|
|
||||||
.REGS_INIT_ZERO (REGS_INIT_ZERO ),
|
|
||||||
.MASKED_IRQ (MASKED_IRQ ),
|
|
||||||
.LATCHED_IRQ (LATCHED_IRQ ),
|
|
||||||
.PROGADDR_RESET (PROGADDR_RESET ),
|
|
||||||
.PROGADDR_IRQ (PROGADDR_IRQ ),
|
|
||||||
.STACKADDR (STACKADDR )
|
|
||||||
) picorv32_core (
|
|
||||||
.clk (clk ),
|
|
||||||
.resetn (resetn),
|
|
||||||
.trap (trap ),
|
|
||||||
|
|
||||||
.mem_valid(mem_valid),
|
|
||||||
.mem_addr (mem_addr ),
|
|
||||||
.mem_wdata(mem_wdata),
|
|
||||||
.mem_wstrb(mem_wstrb),
|
|
||||||
.mem_instr(mem_instr),
|
|
||||||
.mem_ready(mem_ready),
|
|
||||||
.mem_rdata(mem_rdata),
|
|
||||||
|
|
||||||
.pcpi_valid(pcpi_valid),
|
|
||||||
.pcpi_insn (pcpi_insn ),
|
|
||||||
.pcpi_rs1 (pcpi_rs1 ),
|
|
||||||
.pcpi_rs2 (pcpi_rs2 ),
|
|
||||||
.pcpi_wr (pcpi_wr ),
|
|
||||||
.pcpi_rd (pcpi_rd ),
|
|
||||||
.pcpi_wait (pcpi_wait ),
|
|
||||||
.pcpi_ready(pcpi_ready),
|
|
||||||
|
|
||||||
.irq(irq),
|
|
||||||
.eoi(eoi),
|
|
||||||
|
|
||||||
`ifdef RISCV_FORMAL
|
|
||||||
.rvfi_valid (rvfi_valid ),
|
|
||||||
.rvfi_order (rvfi_order ),
|
|
||||||
.rvfi_insn (rvfi_insn ),
|
|
||||||
.rvfi_trap (rvfi_trap ),
|
|
||||||
.rvfi_halt (rvfi_halt ),
|
|
||||||
.rvfi_intr (rvfi_intr ),
|
|
||||||
.rvfi_rs1_addr (rvfi_rs1_addr ),
|
|
||||||
.rvfi_rs2_addr (rvfi_rs2_addr ),
|
|
||||||
.rvfi_rs1_rdata(rvfi_rs1_rdata),
|
|
||||||
.rvfi_rs2_rdata(rvfi_rs2_rdata),
|
|
||||||
.rvfi_rd_addr (rvfi_rd_addr ),
|
|
||||||
.rvfi_rd_wdata (rvfi_rd_wdata ),
|
|
||||||
.rvfi_pc_rdata (rvfi_pc_rdata ),
|
|
||||||
.rvfi_pc_wdata (rvfi_pc_wdata ),
|
|
||||||
.rvfi_mem_addr (rvfi_mem_addr ),
|
|
||||||
.rvfi_mem_rmask(rvfi_mem_rmask),
|
|
||||||
.rvfi_mem_wmask(rvfi_mem_wmask),
|
|
||||||
.rvfi_mem_rdata(rvfi_mem_rdata),
|
|
||||||
.rvfi_mem_wdata(rvfi_mem_wdata),
|
|
||||||
`endif
|
|
||||||
|
|
||||||
.trace_valid(trace_valid),
|
|
||||||
.trace_data (trace_data)
|
|
||||||
);
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* picorv32_axi_adapter
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
module picorv32_axi_adapter (
|
|
||||||
input clk, resetn,
|
|
||||||
|
|
||||||
// AXI4-lite master memory interface
|
|
||||||
|
|
||||||
output mem_axi_awvalid,
|
|
||||||
input mem_axi_awready,
|
|
||||||
output [31:0] mem_axi_awaddr,
|
|
||||||
output [ 2:0] mem_axi_awprot,
|
|
||||||
|
|
||||||
output mem_axi_wvalid,
|
|
||||||
input mem_axi_wready,
|
|
||||||
output [31:0] mem_axi_wdata,
|
|
||||||
output [ 3:0] mem_axi_wstrb,
|
|
||||||
|
|
||||||
input mem_axi_bvalid,
|
|
||||||
output mem_axi_bready,
|
|
||||||
|
|
||||||
output mem_axi_arvalid,
|
|
||||||
input mem_axi_arready,
|
|
||||||
output [31:0] mem_axi_araddr,
|
|
||||||
output [ 2:0] mem_axi_arprot,
|
|
||||||
|
|
||||||
input mem_axi_rvalid,
|
|
||||||
output mem_axi_rready,
|
|
||||||
input [31:0] mem_axi_rdata,
|
|
||||||
|
|
||||||
// Native PicoRV32 memory interface
|
|
||||||
|
|
||||||
input mem_valid,
|
|
||||||
input mem_instr,
|
|
||||||
output mem_ready,
|
|
||||||
input [31:0] mem_addr,
|
|
||||||
input [31:0] mem_wdata,
|
|
||||||
input [ 3:0] mem_wstrb,
|
|
||||||
output [31:0] mem_rdata
|
|
||||||
);
|
|
||||||
reg ack_awvalid;
|
|
||||||
reg ack_arvalid;
|
|
||||||
reg ack_wvalid;
|
|
||||||
reg xfer_done;
|
|
||||||
|
|
||||||
assign mem_axi_awvalid = mem_valid && |mem_wstrb && !ack_awvalid;
|
|
||||||
assign mem_axi_awaddr = mem_addr;
|
|
||||||
assign mem_axi_awprot = 0;
|
|
||||||
|
|
||||||
assign mem_axi_arvalid = mem_valid && !mem_wstrb && !ack_arvalid;
|
|
||||||
assign mem_axi_araddr = mem_addr;
|
|
||||||
assign mem_axi_arprot = mem_instr ? 3'b100 : 3'b000;
|
|
||||||
|
|
||||||
assign mem_axi_wvalid = mem_valid && |mem_wstrb && !ack_wvalid;
|
|
||||||
assign mem_axi_wdata = mem_wdata;
|
|
||||||
assign mem_axi_wstrb = mem_wstrb;
|
|
||||||
|
|
||||||
assign mem_ready = mem_axi_bvalid || mem_axi_rvalid;
|
|
||||||
assign mem_axi_bready = mem_valid && |mem_wstrb;
|
|
||||||
assign mem_axi_rready = mem_valid && !mem_wstrb;
|
|
||||||
assign mem_rdata = mem_axi_rdata;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
if (!resetn) begin
|
|
||||||
ack_awvalid <= 0;
|
|
||||||
end else begin
|
|
||||||
xfer_done <= mem_valid && mem_ready;
|
|
||||||
if (mem_axi_awready && mem_axi_awvalid)
|
|
||||||
ack_awvalid <= 1;
|
|
||||||
if (mem_axi_arready && mem_axi_arvalid)
|
|
||||||
ack_arvalid <= 1;
|
|
||||||
if (mem_axi_wready && mem_axi_wvalid)
|
|
||||||
ack_wvalid <= 1;
|
|
||||||
if (xfer_done || !mem_valid) begin
|
|
||||||
ack_awvalid <= 0;
|
|
||||||
ack_arvalid <= 0;
|
|
||||||
ack_wvalid <= 0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
* picorv32_wb
|
* picorv32_wb
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
@ -2837,7 +2565,9 @@ module picorv32_wb #(
|
||||||
parameter [31:0] PROGADDR_IRQ = 32'h 0000_0010,
|
parameter [31:0] PROGADDR_IRQ = 32'h 0000_0010,
|
||||||
parameter [31:0] STACKADDR = 32'h ffff_ffff
|
parameter [31:0] STACKADDR = 32'h ffff_ffff
|
||||||
) (
|
) (
|
||||||
output trap,
|
output [7:0] trap,
|
||||||
|
output [31:0] dbg_insn_addr,
|
||||||
|
output [31:0] dbg_insn_opcode,
|
||||||
|
|
||||||
// Wishbone interfaces
|
// Wishbone interfaces
|
||||||
input wb_rst_i,
|
input wb_rst_i,
|
||||||
|
@ -2981,6 +2711,8 @@ module picorv32_wb #(
|
||||||
.rvfi_mem_rdata(rvfi_mem_rdata),
|
.rvfi_mem_rdata(rvfi_mem_rdata),
|
||||||
.rvfi_mem_wdata(rvfi_mem_wdata),
|
.rvfi_mem_wdata(rvfi_mem_wdata),
|
||||||
`endif
|
`endif
|
||||||
|
.dbg_insn_addr(dbg_insn_addr),
|
||||||
|
.dbg_insn_opcode(dbg_insn_opcode),
|
||||||
|
|
||||||
.trace_valid(trace_valid),
|
.trace_valid(trace_valid),
|
||||||
.trace_data (trace_data)
|
.trace_data (trace_data)
|
||||||
|
|
|
@ -367,7 +367,17 @@ class PicoRV32(Module, AutoCSR):
|
||||||
self.masterbus = Interface(data_width=32, address_width=32, addressing="byte")
|
self.masterbus = Interface(data_width=32, address_width=32, addressing="byte")
|
||||||
|
|
||||||
self.resetpin = CSRStorage(1, name="enable", description="PicoRV32 enable")
|
self.resetpin = CSRStorage(1, name="enable", description="PicoRV32 enable")
|
||||||
self.trap = CSRStatus(1, name="trap", description="Trap bit")
|
|
||||||
|
self.trap = CSRStatus(8, name="trap", description="Trap condition")
|
||||||
|
self.d_adr = CSRStatus(32)
|
||||||
|
self.d_dat_w = CSRStatus(32)
|
||||||
|
self.dbg_insn_addr = CSRStatus(32)
|
||||||
|
self.dbg_insn_opcode = CSRStatus(32)
|
||||||
|
|
||||||
|
self.comb += [
|
||||||
|
self.d_adr.status.eq(self.masterbus.adr),
|
||||||
|
self.d_dat_w.status.eq(self.masterbus.dat_w),
|
||||||
|
]
|
||||||
|
|
||||||
# NOTE: need to compile to these extact instructions
|
# NOTE: need to compile to these extact instructions
|
||||||
self.specials += Instance("picorv32_wb",
|
self.specials += Instance("picorv32_wb",
|
||||||
|
@ -404,10 +414,13 @@ class PicoRV32(Module, AutoCSR):
|
||||||
o_trace_valid = Signal(),
|
o_trace_valid = Signal(),
|
||||||
o_trace_data = Signal(36),
|
o_trace_data = Signal(36),
|
||||||
o_debug_state = Signal(2),
|
o_debug_state = Signal(2),
|
||||||
|
|
||||||
|
o_dbg_insn_addr = self.dbg_insn_addr.status,
|
||||||
|
o_dbg_insn_opcode = self.dbg_insn_opcode.status,
|
||||||
)
|
)
|
||||||
|
|
||||||
def do_finalize(self):
|
def do_finalize(self):
|
||||||
self.mmap.dump_json(self.name)
|
self.mmap.dump_json(self.name + ".json")
|
||||||
self.submodules.decoder = self.mmap.bus_submodule(self.masterbus)
|
self.submodules.decoder = self.mmap.bus_submodule(self.masterbus)
|
||||||
|
|
||||||
# Clock and Reset Generator
|
# Clock and Reset Generator
|
||||||
|
|
|
@ -5,21 +5,29 @@ def read_file(filename):
|
||||||
with open(filename, 'rb') as f:
|
with open(filename, 'rb') as f:
|
||||||
return f.read()
|
return f.read()
|
||||||
|
|
||||||
|
def check_running():
|
||||||
|
print("Running:", machine.mem32[pico0_enable])
|
||||||
|
print("Trap status:", machine.mem32[pico0_trap])
|
||||||
|
print("Bus address:", hex(machine.mem32[pico0_d_adr]))
|
||||||
|
print("Bus write value:", hex(machine.mem32[pico0_d_dat_w]))
|
||||||
|
print("Instruction address:", hex(machine.mem32[pico0_dbg_insn_addr]))
|
||||||
|
print("Opcode:", hex(machine.mem32[pico0_dbg_insn_opcode]))
|
||||||
|
|
||||||
def run_program(prog, cl_I):
|
def run_program(prog, cl_I):
|
||||||
# Reset PicoRV32
|
# Reset PicoRV32
|
||||||
machine.mem32[picorv32_enable] = 0
|
machine.mem32[pico0_enable] = 0
|
||||||
machine.mem32[picorv32_ram_iface_master_select] = 0
|
machine.mem32[pico0ram_iface_master_select] = 0
|
||||||
|
|
||||||
offset = picorv32_ram
|
offset = pico0_ram
|
||||||
for b in prog:
|
for b in prog:
|
||||||
machine.mem8[offset] = b
|
machine.mem8[offset] = b
|
||||||
offset += 1
|
offset += 1
|
||||||
|
|
||||||
for i in range(len(prog)):
|
for i in range(len(prog)):
|
||||||
assert machine.mem8[picorv32_ram + i] == prog[i]
|
assert machine.mem8[pico0_ram + i] == prog[i]
|
||||||
|
|
||||||
machine.mem32[picorv32_ram_iface_master_select] = 1
|
machine.mem32[pico0_params_cl_I] = cl_I
|
||||||
assert machine.mem8[picorv32_ram] == 0
|
machine.mem32[pico0ram_iface_master_select] = 1
|
||||||
machine.mem32[picorv32_params_cl_I] = cl_I
|
assert machine.mem8[pico0_ram] == 0
|
||||||
machine.mem32[picorv32_enable] = 1
|
machine.mem32[pico0_enable] = 1
|
||||||
return machine.mem32[picorv32_params_zset]
|
return machine.mem32[pico0_params_zset]
|
||||||
|
|
Loading…
Reference in New Issue