Commit 0e4dc0d4 authored by Tristan Gingold's avatar Tristan Gingold Committed by Dimitris Lampridis

debug: can load a program using debug mode.

parent 6b2e105e
......@@ -62,7 +62,7 @@ module urv_cpu
// immediate. Interrupts are disabled in debug mode.
// In debug mode, instructions are executed from dbg_insn_i. An instruction
// is fetched when dbg_insn_read_o is set. As instructions are always
// fetched, they must be always valid. Use a nop (0x19) if nothing should
// fetched, they must be always valid. Use a nop (0x13) if nothing should
// be executed.
input dbg_force_i,
output dbg_enabled_o,
......@@ -70,10 +70,11 @@ module urv_cpu
output dbg_insn_ready_o,
input [31:0] dbg_mbxi_data_i,
input dbg_mbxi_valid_i,
input dbg_mbxi_write_i,
output dbg_mbxi_full_o,
output [31:0] dbg_mbxo_data_o,
output dbg_mbxo_valid_o,
input dbg_mbxo_read_i
input dbg_mbxo_read_i,
output dbg_mbxo_full_o
);
......@@ -178,7 +179,7 @@ module urv_cpu
.dbg_enabled_o(dbg_enabled_o),
.dbg_insn_i(dbg_insn_i),
.dbg_insn_ready_o(dbg_insn_ready_o),
.x_dbg_toggle(x_dbg_toggle)
.x_dbg_toggle(x2f_dbg_toggle)
);
......@@ -335,10 +336,11 @@ module urv_cpu
// Debug mailboxes
.dbg_mbxi_data_i(dbg_mbxi_data_i),
.dbg_mbxi_valid_i(dbg_mbxi_valid_i),
.dbg_mbxi_write_i(dbg_mbxi_write_i),
.dbg_mbxi_full_o(dbg_mbxi_full_o),
.dbg_mbxo_data_o(dbg_mbxo_data_o),
.dbg_mbxo_valid_o(dbg_mbxo_valid_o),
.dbg_mbxo_read_i(dbg_mbxo_read_i)
.dbg_mbxo_read_i(dbg_mbxo_read_i),
.dbg_mbxo_full_o(dbg_mbxo_full_o)
);
// Execute 2/Writeback stage
......
......@@ -56,10 +56,11 @@ module urv_csr
// Debug mailboxes
input [31:0] dbg_mbxi_data_i,
input dbg_mbxi_valid_i,
input dbg_mbxi_write_i,
output dbg_mbxi_full_o,
output [31:0] dbg_mbxo_data_o,
output dbg_mbxo_valid_o,
input dbg_mbxo_read_i
input dbg_mbxo_read_i,
output dbg_mbxo_full_o
);
reg [31:0] csr_mscratch;
......@@ -86,7 +87,10 @@ module urv_csr
`CSR_ID_MCAUSE: csr_in1 <= csr_mcause_i;
`CSR_ID_MIP: csr_in1 <= csr_mip_i;
`CSR_ID_MIE: csr_in1 <= csr_mie_i;
`CSR_ID_DBGSTATUS: csr_in1 <= {30'b0, mbxo_valid, mbxi_valid};
`CSR_ID_DBGSCRATCH: csr_in1 <= csr_dbg_scratch;
`CSR_ID_DBGMBXI: csr_in1 <= mbxi_data;
`CSR_ID_DBGMBXO: csr_in1 <= mbxo_data;
default: csr_in1 <= 32'hx;
endcase // case (d_csr_sel_i)
......@@ -134,7 +138,7 @@ module urv_csr
begin
if (dbg_mbxo_read_i)
mbxo_valid <= 0;
if (dbg_mbxi_valid_i)
if (dbg_mbxi_write_i)
begin
mbxi_data <= dbg_mbxi_data_i;
mbxi_valid <= 1;
......@@ -157,7 +161,8 @@ module urv_csr
end // else: !if(rst_i)
assign dbg_mbxo_data_o = mbxo_data;
assign dbg_mbxo_valid_o = mbxo_valid;
assign dbg_mbxo_full_o = mbxo_valid;
assign dbg_mbxi_full_o = mbxi_valid;
assign x_csr_write_value_o = csr_out;
endmodule
......@@ -84,8 +84,8 @@
`define CSR_ID_MIE 12'h304
`define CSR_ID_DBGSTATUS 12'h7c0
`define CSR_ID_DBGSCRATCH 12'h7c4
`define CSR_ID_DBGMBXO 12'h7d0
`define CSR_ID_DBGMBXI 12'h7d4
`define CSR_ID_DBGMBXI 12'h7d0
`define CSR_ID_DBGMBXO 12'h7d4
`define CSR_OP_CSRRW 3'b001
`define CSR_OP_CSRRS 3'b010
......
......@@ -108,10 +108,11 @@ module urv_exec
// Debug mailboxes.
input [31:0] dbg_mbxi_data_i,
input dbg_mbxi_valid_i,
input dbg_mbxi_write_i,
output dbg_mbxi_full_o,
output [31:0] dbg_mbxo_data_o,
output dbg_mbxo_valid_o,
input dbg_mbxo_read_i
input dbg_mbxo_read_i,
output dbg_mbxo_full_o
);
wire [31:0] rs1, rs2;
......@@ -178,10 +179,11 @@ module urv_exec
.csr_mcause_i(csr_mcause),
.dbg_mbxi_data_i(dbg_mbxi_data_i),
.dbg_mbxi_valid_i(dbg_mbxi_valid_i),
.dbg_mbxi_write_i(dbg_mbxi_write_i),
.dbg_mbxi_full_o(dbg_mbxi_full_o),
.dbg_mbxo_data_o(dbg_mbxo_data_o),
.dbg_mbxo_valid_o(dbg_mbxo_valid_o),
.dbg_mbxo_read_i(dbg_mbxo_read_i)
.dbg_mbxo_read_i(dbg_mbxo_read_i),
.dbg_mbxo_full_o(dbg_mbxo_full_o)
);
urv_exceptions exception_unit
......
......@@ -61,7 +61,7 @@ module urv_fetch
always@*
if( x_bra_i )
pc_next <= x_pc_bra_i;
else if (!rst_d || f_stall_i || !im_valid_i)
else if (!rst_d || f_stall_i || !im_valid_i || dbg_mode)
pc_next <= pc;
else
pc_next <= pc_plus_4;
......@@ -78,12 +78,13 @@ module urv_fetch
pc <= 0;
pc_plus_4 <= 4;
f_pc_o <= 0;
f_ir_o <= 0;
f_valid_o <= 0;
// Allow to start in debug mode.
dbg_mode <= dbg_force_i;
dbg_insn_ready_o <= dbg_force_i;
dbg_insn_ready_o <= 0;
pipeline_cnt <= 0;
......@@ -98,12 +99,13 @@ module urv_fetch
if (!f_stall_i)
begin
f_pc_o <= pc;
pc <= pc_next;
if((dbg_force_i || x_dbg_toggle) && !dbg_mode)
begin
// Try to enter in debug mode.
f_valid_o <= 0;
if (pipeline_cnt == 5)
if (pipeline_cnt == 4)
dbg_mode <= 1;
else
pipeline_cnt <= pipeline_cnt + 1;
......@@ -113,6 +115,8 @@ module urv_fetch
// Default: insn not valid
f_valid_o <= 0;
pc_plus_4 <= pc + 4;
if (x_dbg_toggle)
begin
// Leave debug mode
......@@ -127,7 +131,7 @@ module urv_fetch
dbg_insn_ready_o <= 0;
pipeline_cnt <= 0;
end
else if (pipeline_cnt == 5)
else if (pipeline_cnt == 4)
dbg_insn_ready_o <= 1;
else
pipeline_cnt <= pipeline_cnt + 1;
......@@ -136,14 +140,13 @@ module urv_fetch
begin
pc_plus_4 <= (x_bra_i ? x_pc_bra_i : pc_plus_4) + 4;
f_ir_o <= im_data_i;
// A branch invalidate the current instruction.
f_valid_o <= (rst_d && !x_bra_i);
end
else
begin// if (i_valid_i)
f_valid_o <= 0;
end
pc <= pc_next;
end
end
......
......@@ -45,7 +45,6 @@ module main;
reg dm_ready;
localparam int mem_size = 16384;
reg [31:0] mem[0:mem_size - 1];
......
RISCV_PREFIX=riscv32-elf-
RISCV_GCC = $(RISCV_PREFIX)gcc
SW_DIR=../../sw
CFLAGS = -march=rv32im -mabi=ilp32 -DSIM -I$(SW_DIR)/common
all: app1.bin
app1: crt0.o app1.o uart.o
$(RISCV_GCC) -o $@ $^ -nostdlib -T $(SW_DIR)/common/ram2.ld -Wl,-Map,$@.map
app1.bin: app1
$(RISCV_PREFIX)objcopy -O binary $< $<.bin
crt0.o: $(SW_DIR)/crt0.S
$(RISCV_GCC) -c $(CFLAGS) -o $@ $<
uart.o: $(SW_DIR)/common/uart.c
$(RISCV_GCC) -c $(CFLAGS) -o $@ $<
app1.o: app1.c
$(RISCV_GCC) -c $(CFLAGS) -o $@ $<
int main(void)
{
puts("Hello world\n");
asm volatile("ebreak");
return 0;
}
.text
# Set dest address
li a0, 0
# Read count (in bytes)
1: csrr t0, 0x7c0 # dbg status
andi t0, t0, 1
beq t0, zero, 1b
csrr a1, 0x7d0 # mbxi
# Read data
1: csrr t0, 0x7c0 # dbg status
andi t0, t0, 1
beq t0, zero, 1b
csrr t1, 0x7d0 # mbxi
sw t1, 0(a0)
addi a0, a0, 4
blt a0, a1, 1b
# Start at 0
done: li a0, 0
jr a0
.text
# Init
nop
# Write one word
csrr t0, 0x7d0
csrr t1, 0x7d0
sw t1, 0(t0)
# Jump to t0
jalr x0, t0, 0
ebreak
......@@ -50,7 +50,8 @@ module main;
wire dbg_insn_ready;
reg [31:0] mbxi_data;
reg mbxi_valid;
reg mbxi_write;
wire mbxi_full;
const var [31:0] insn_nop = 32'h13;
......@@ -60,21 +61,20 @@ module main;
const var [31:0] insn_jr_t0 = 32'h00028067;
const var [31:0] insn_ebreak = 32'h00100073;
const var [31:0] loader [15] = '{ 32'h00000013,
32'h00000513,
32'h7c0022f3,
32'h0012f293,
32'hfe028ce3,
32'h7d0025f3,
32'h02058063,
32'h7c0022f3,
32'h0012f293,
32'hfe028ce3,
32'h7d002373,
32'h00652023,
32'h00450513,
32'hfeb514e3,
32'h00100073 };
const var [31:0] loader [14] = '{ 32'h00000513, // li a0,0
32'h7c0022f3, // csrr t0,0x7c0
32'h0012f293, // andi t0,t0,1
32'hfe028ce3, // beqz t0,-8
32'h7d0025f3, // csrr a1,0x7d0
32'h7c0022f3, // csrr t0,0x7c0
32'h0012f293, // andi t0,t0,1
32'hfe028ce3, // beqz t0,-8
32'h7d002373, // csrr t1,0x7d0
32'h00652023, // sw t1,0(a0)
32'h00450513, // addi a0,a0,4
32'hfeb544e3, // blt a0,a1,-24
32'h00000513, // li a0,0
32'h00050067}; // jr a0
localparam int mem_size = 16384;
......@@ -163,9 +163,10 @@ module main;
// Debug mailboxes
.dbg_mbxi_data_i(mbxi_data),
.dbg_mbxi_valid_i(mbxi_valid),
.dbg_mbxi_write_i(mbxi_write),
.dbg_mbxi_full_o(mbxi_full),
.dbg_mbxo_data_o(),
.dbg_mbxo_valid_o(),
.dbg_mbxo_full_o(),
.dbg_mbxo_read_i(1'b0)
);
......@@ -179,6 +180,16 @@ module main;
@(posedge clk);
endtask // send_insn
task send_mbxi(input [31:0] data);
mbxi_data <= data;
mbxi_write <= 1;
@(posedge clk);
mbxi_write <= 0;
@(posedge clk);
while(mbxi_full)
@(posedge clk);
endtask
initial begin
// load_ram("../../sw/test3/test3.ram");
// load_ram("../../sw/testsuite/benchmarks/dhrystone/dhrystone.ram");
......@@ -189,7 +200,7 @@ module main;
dbg_insn = insn_nop;
mbxi_data <= 0;
mbxi_valid <= 0;
mbxi_write <= 0;
repeat(3) @(posedge clk);
rst = 0;
......@@ -201,12 +212,12 @@ module main;
begin
// Address
mbxi_data <= loader_addr + i * 4;
mbxi_valid <= 1;
mbxi_write <= 1;
send_insn (insn_csrr_t0_mbxi);
// Insn
mbxi_data <= loader[i];
mbxi_valid <= 1;
mbxi_write <= 1;
send_insn (insn_csrr_t1_mbxi);
// Store
......@@ -215,11 +226,11 @@ module main;
// Set PC address
mbxi_data <= loader_addr;
mbxi_valid <= 1;
mbxi_write <= 1;
send_insn (insn_csrr_t0_mbxi);
// Branch.
mbxi_valid <= 0;
mbxi_write <= 0;
send_insn (insn_jr_t0);
// Flush mailbox.
......@@ -227,6 +238,31 @@ module main;
send_insn (insn_ebreak);
dbg_insn <= insn_nop;
// Use loader to load the program.
begin
int fd;
int filelen;
fd = $fopen("app1.bin", "rb");
void'($fseek(fd, 0, 2));
filelen = $ftell(fd);
void'($rewind(fd));
send_mbxi(filelen);
filelen = (filelen + 3) / 4;
for(int i = 0; i < filelen; i++)
begin
var [7:0] b0, b1, b2, b3;
int l;
l = $fread(b0, fd);
l += $fread(b1, fd);
l += $fread(b2, fd);
l += $fread(b3, fd);
// LE.
send_mbxi({b3, b2, b1, b0});
end
$fclose(fd);
end
end
function string decode_op(bit[2:0] fun);
......@@ -510,6 +546,18 @@ module main;
rd, decode_csr(DUT.d2x_csr_sel),
rs1, DUT.execute.rs1);
end
`CSR_OP_CSRRS: begin
opc = "csrrs";
args = $sformatf("%-3s %-3s %-3s [0x%08x]",
rd, decode_csr(DUT.d2x_csr_sel),
rs1, DUT.execute.rs1);
end
`CSR_OP_CSRRC: begin
opc = "csrrc";
args = $sformatf("%-3s %-3s %-3s [0x%08x]",
rd, decode_csr(DUT.d2x_csr_sel),
rs1, DUT.execute.rs1);
end
default: begin
opc = "system";
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment