URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/orpsocv2/bench/verilog
- from Rev 361 to Rev 397
- ↔ Reverse comparison
Rev 361 → Rev 397
/orpsoc_testbench.v
201,6 → 201,7
); |
|
// UART0 stimulus |
/* |
uart_stim |
#( |
.uart_baudrate_period_ns(8680) // 115200 baud = period 8.68uS |
210,7 → 211,10
.clk(clk), |
.uart_rx(uart0_srx_pad_i) |
); |
|
*/ |
// UART0 is looped back for now |
assign uart0_srx_pad_i = uart0_stx_pad_o; |
|
`endif // `ifdef UART0 |
|
endmodule // orpsoc_testbench |
/or1200_monitor.v
41,18 → 41,36
// |
`define OR1200_TOP orpsoc_testbench.dut.or1200_top |
|
// |
// Define to enable lookup file generation |
// |
//`define OR1200_MONITOR_LOOKUP |
|
// |
// Enable display_arch_state task |
// Define to enable SPR access log file generation |
// |
//`define OR1200_DISPLAY_ARCH_STATE |
//`define OR1200_MONITOR_SPRS |
|
// |
// Enable disassembly of instructions in execution log |
// Enable logging of state during execution |
// |
//`define OR1200_MONITOR_EXEC_STATE |
|
// |
// Enable disassembly of instructions in execution state log |
// |
//`define OR1200_MONITOR_PRINT_DISASSEMBLY |
|
// Can either individually enable things above, or usually have the scripts |
// running the simulation pass the PROCESSOR_MONITOR_ENABLE_LOGS define to |
// enable them all. |
|
`ifdef PROCESSOR_MONITOR_ENABLE_LOGS |
`define OR1200_MONITOR_EXEC_STATE |
`define OR1200_MONITOR_SPRS |
`define OR1200_MONITOR_LOOKUP |
`endif |
|
// |
// Top of OR1200 inside test bench |
// |
67,9 → 85,13
|
integer fexe; |
reg [23:0] ref; |
`ifdef OR1200_MONITOR_SPRS |
integer fspr; |
`endif |
integer fgeneral; |
`ifdef OR1200_MONITOR_LOOKUP |
integer flookup; |
`endif |
integer r3; |
integer insns; |
|
79,11 → 101,17
// |
initial begin |
ref = 0; |
`ifdef OR1200_MONITOR_EXEC_STATE |
fexe = $fopen({"../out/",`TEST_NAME_STRING,"-executed.log"}); |
`endif |
$timeformat (-9, 2, " ns", 12); |
`ifdef OR1200_MONITOR_SPRS |
fspr = $fopen({"../out/",`TEST_NAME_STRING,"-sprs.log"}); |
`endif |
fgeneral = $fopen({"../out/",`TEST_NAME_STRING,"-general.log"}); |
`ifdef OR1200_MONITOR_LOOKUP |
flookup = $fopen({"../out/",`TEST_NAME_STRING,"-lookup.log"}); |
`endif |
insns = 0; |
|
end |
123,9 → 151,11
reg [31:0] r; |
integer j; |
begin |
`ifdef OR1200_DISPLAY_ARCH_STATE |
`ifdef OR1200_MONITOR_EXEC_STATE |
ref = ref + 1; |
`ifdef OR1200_MONITOR_LOOKUP |
$fdisplay(flookup, "Instruction %d: %t", insns, $time); |
`endif |
$fwrite(fexe, "\nEXECUTED(%d): %h: %h", insns, |
`OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc, |
`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn); |
149,10 → 179,12
$fwrite(fexe, "EEAR0: %h ", r); |
r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.esr; |
$fdisplay(fexe, "ESR0 : %h", r); |
`endif // `ifdef OR1200_DISPLAY_ARCH_STATE |
`endif // `ifdef OR1200_MONITOR_EXEC_STATE |
`ifdef OR1200_DISPLAY_EXECUTED |
ref = ref + 1; |
`ifdef OR1200_MONITOR_LOOKUP |
$fdisplay(flookup, "Instruction %d: %t", insns, $time); |
`endif |
$fwrite(fexe, "\nEXECUTED(%d): %h: %h", insns, `OR1200_TOP.`CPU_cpu.`CPU_except.wb_pc, `OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn); |
`endif |
insns = insns + 1; |
219,9 → 251,11
reg [31:0] r; |
integer j; |
begin |
`ifdef OR1200_DISPLAY_ARCH_STATE |
`ifdef OR1200_MONITOR_EXEC_STATE |
ref = ref + 1; |
`ifdef OR1200_MONITOR_LOOKUP |
$fdisplay(flookup, "Instruction %d: %t", insns, $time); |
`endif |
$fwrite(fexe, "\nEXECUTED(%d): %h: %h (exception)", insns, `OR1200_TOP.`CPU_cpu.`CPU_except.ex_pc, `OR1200_TOP.`CPU_cpu.`CPU_ctrl.ex_insn); |
for(i = 0; i < 32; i = i + 1) begin |
if (i % 4 == 0) |
239,10 → 273,12
r = `OR1200_TOP.`CPU_cpu.`CPU_sprs.esr; |
$fdisplay(fexe, "ESR0 : %h", r); |
insns = insns + 1; |
`endif // `ifdef OR1200_DISPLAY_ARCH_STATE |
`endif // `ifdef OR1200_MONITOR_EXEC_STATE |
`ifdef OR1200_DISPLAY_EXECUTED |
ref = ref + 1; |
`ifdef OR1200_MONITOR_LOOKUP |
$fdisplay(flookup, "Instruction %d: %t", insns, $time); |
`endif |
$fwrite(fexe, "\nEXECUTED(%d): %h: %h (exception)", insns, |
`OR1200_TOP.`CPU_cpu.`CPU_except.ex_pc, |
`OR1200_TOP.`CPU_cpu.`CPU_ctrl.ex_insn); |
371,9 → 407,6
// debug if test (l.nop 10) |
if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_000a) begin |
$fdisplay(fgeneral, "%t: l.nop dbg_if_test", $time); |
`ifdef DBG_IF_MODEL |
xess_top.i_xess_fpga.dbg_if_model.dbg_if_test_go = 1; |
`endif |
end |
// simulation reports (l.nop 2) |
if (`OR1200_TOP.`CPU_cpu.`CPU_ctrl.wb_insn == 32'h1500_0002) begin |
391,16 → 424,17
$write("%c", r3); |
$fdisplay(fgeneral, "%t: l.nop putc (%c)", $time, r3); |
end |
if (`OR1200_TOP.`CPU_cpu.alu_op/*`CPU_sprs.sprs_op*/ == |
`OR1200_ALUOP_MTSR) // l.mtspr |
`ifdef OR1200_MONITOR_SPRS |
if (`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_we) |
$fdisplay(fspr, "%t: Write to SPR : [%h] <- %h", $time, |
`OR1200_TOP.`CPU_cpu.alu_op/*`CPU_sprs.spr_addr*/, |
`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_addr, |
`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_dat_o); |
if (`OR1200_TOP.`CPU_cpu.alu_op/*`CPU_sprs.sprs_op*/ == |
`OR1200_ALUOP_MFSR) // l.mfspr |
if ((|`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_cs) & |
!`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_we) |
$fdisplay(fspr, "%t: Read from SPR: [%h] -> %h", $time, |
`OR1200_TOP.`CPU_cpu.`CPU_sprs.spr_addr, |
`OR1200_TOP.`CPU_cpu.`CPU_sprs.to_wbmux); |
`endif |
end |
|
|
/vpi/c/rsp-rtl_sim.h
38,20 → 38,25
|
#include <stdint.h> // For uint32_t types |
|
//#define DEBUG 1 |
//#define DEBUG2 1 |
#define DEBUG 0 |
#define DEBUG2 0 |
#define DBG_ON 0 |
#define DBG_JP_VPI 0 |
#define DBG_VPI 0 |
#define DBG_CALLS 0 |
|
|
#define Boolean int |
#define false 0 |
#define true 1 |
|
#ifdef DEBUG |
#if DEBUG==1 |
#define debug printf |
#else |
#define debug |
#endif |
|
#ifdef DEBUG2 |
#if DEBUG2==1 |
#define debug2 printf |
#else |
#define debug2 |
58,14 → 63,6
#endif |
|
|
#define DBG_ON 0 |
|
#define DBG_JP_VPI 0 |
|
#define DBG_VPI 0 |
|
#define DBG_CALLS 0 |
|
extern uint32_t vpi_to_rsp_pipe[2]; // [0] - read, [1] - write |
extern uint32_t rsp_to_vpi_pipe[2]; // [0] - read, [1] - write |
extern uint32_t command_pipe[2]; // RSP end writes, VPI end reads ONLY |
90,6 → 87,7
|
/* read a word from wishbone */ |
int dbg_wb_read32(uint32_t adr, uint32_t *data); |
int dbg_wb_read8(uint32_t adr, uint8_t* data); |
|
/* write a word to wishbone */ |
int dbg_wb_write32(uint32_t adr, uint32_t data); |
/vpi/c/rsp-vpi.h
55,9 → 55,9
// 4'hb reset |
// 4'hc read jtag id (output: data) |
// 4'hd GDB detach - do something (like close down, restart, etc.) |
|
// 4'he wb rd 8 (input: address, data pointer) |
// There should be a correlating set of verilog `define's in the |
// verilog debug testbench module's include file, test_defines.v |
// verilog debug testbench module's include file, vpi_debug_defines.v |
|
#define CMD_JTAG_SET_IR 0x1 |
#define CMD_SET_DEBUG_CHAIN 0x2 |
72,3 → 72,4
#define CMD_RESET 0xb |
#define CMD_READ_JTAG_ID 0xc |
#define CMD_GDB_DETACH 0xd |
#define CMD_WB_RD8 0xe |
/vpi/c/jp_vpi.c
180,7 → 180,7
#include "rsp-vpi.h" |
|
// Define the port we open the RSP server on |
#define RSP_SERVER_PORT 5555 |
#define RSP_SERVER_PORT 50002 |
|
//Function to register the function which sets up the sockets interface |
void register_init_rsp_server_functions() ; |
397,6 → 397,12
case 0xc : |
printf(" read jtag id\n"); |
break; |
case 0xd : |
printf(" detach\n"); |
break; |
case 0xe : |
printf(" WB read 8\n"); |
break; |
} |
} |
|
629,9 → 635,14
argh = vpi_scan(args_iter); |
|
// check we got passed a memory (array of regs) |
if (vpi_get(vpiType, argh) != vpiMemory) |
if (!((vpi_get(vpiType, argh) == vpiMemory) |
#ifdef MODELSIM_VPI |
|| (vpi_get(vpiType, argh) == vpiRegArray) |
#endif |
)) |
{ |
vpi_printf("jp_vpi: ERROR: did not pass a memory to get_command_block_data\n"); |
vpi_printf("jp_vpi: ERROR: was passed type %d\n", (int)vpi_get(vpiType, argh)); |
return; |
} |
|
691,7 → 702,7
|
int value,i; |
|
int n; |
int n, length; |
|
uint32_t data; |
|
703,6 → 714,17
// Now call iterate with the vpiArgument parameter |
args_iter = vpi_iterate(vpiArgument, systfref); |
|
// get a handle on the length variable |
argh = vpi_scan(args_iter); |
|
argval.format = vpiIntVal; |
|
// get the value for the length object |
vpi_get_value(argh, &argval); |
|
// now set length |
length = argval.value.integer; |
|
// get a handle on the object passed to the function |
argh = vpi_scan(args_iter); |
|
717,12 → 739,12
// Cleanup and return |
vpi_free_object(args_iter); |
|
if (DBG_JP_VPI) printf("jp_vpi: return_command_data 0x%.8x\n",data); |
if (DBG_JP_VPI) printf("jp_vpi: return_command_data %d bytes, 0x%.8x\n",length,data); |
|
send_buf = (char *) &data; //cast our long as a char buf |
|
// write the data back |
n = write(vpi_to_rsp_pipe[1],send_buf,4); |
n = write(vpi_to_rsp_pipe[1],send_buf,length); |
|
return; |
|
770,10 → 792,15
// now get a handle on the next object (memory array) |
argh = vpi_scan(args_iter); |
|
// check we got passed a memory (array of regs) |
if (vpi_get(vpiType, argh) != vpiMemory) |
// check we got passed a memory (array of regs) (modelsim passes back a vpiRegArray, so check for that too) |
if (!((vpi_get(vpiType, argh) == vpiMemory) |
#ifdef MODELSIM_VPI |
|| (vpi_get(vpiType, argh) == vpiRegArray) |
#endif |
)) |
{ |
vpi_printf("jp_vpi: ERROR: did not pass a memory to return_command_block_data\n"); |
vpi_printf("jp_vpi: ERROR: was passed type %d\n", (int)vpi_get(vpiType, argh)); |
return; |
} |
|
/vpi/c/rsp-rtl_sim.c
78,7 → 78,8
|
/* VPI communication prototyopes */ |
static void get_response_from_vpi(); |
static void get_data_from_vpi(); |
static void get_word_from_vpi(); |
static void get_byte_from_vpi(); |
static void get_block_data_from_vpi(int len, uint32_t *data); |
static void send_data_to_vpi(uint32_t data); |
static void send_block_data_to_vpi(int len, uint32_t *data); |
162,11 → 163,33
|
} |
|
void get_data_from_vpi(uint32_t* data) |
|
void get_byte_from_vpi(uint8_t* data) |
{ |
|
int n; |
|
uint8_t inc_data; |
|
char* recv_buf; |
|
recv_buf = (char*) &inc_data; |
|
n = read(vpi_to_rsp_pipe[0],recv_buf,1); // block and wait for the data |
|
if (DBG_VPI) printf("rsp-rtl_sim: get_byte_from_vpi: 0x%.8x\n",inc_data); |
|
*data = inc_data; |
|
return; |
|
} |
|
void get_word_from_vpi(uint32_t* data) |
{ |
|
int n; |
|
uint32_t inc_data; |
|
char* recv_buf; |
175,7 → 198,7
|
n = read(vpi_to_rsp_pipe[0],recv_buf,4); // block and wait for the data |
|
if (DBG_VPI) printf("rsp-rtl_sim: get_data_from_vpi: 0x%.8x\n",inc_data); |
if (DBG_VPI) printf("rsp-rtl_sim: get_word_from_vpi: 0x%.8x\n",inc_data); |
|
*data = inc_data; |
|
233,9 → 256,11
int n = 0; |
char tmp; |
|
if (DBG_CALLS)printf("get_response_from_vpi\n"); |
if (DBG_CALLS)printf("get_response_from_vpi.."); |
|
n = read(vpi_to_rsp_pipe[0],&tmp,1); // block and wait |
|
if (DBG_CALLS)printf("OK\n"); |
|
return; |
} |
271,8 → 296,8
/* now read out the jtag id */ |
send_command_to_vpi(CMD_READ_JTAG_ID); |
|
//id = get_data_from_vpi(); |
get_data_from_vpi((uint32_t *)&id); |
//id = get_word_from_vpi(); |
get_word_from_vpi((uint32_t *)&id); |
|
get_response_from_vpi(); |
|
374,7 → 399,7
|
send_command_to_vpi(CMD_CPU_CTRL_RD); |
|
get_data_from_vpi((uint32_t *)&resp); |
get_word_from_vpi((uint32_t *)&resp); |
|
if (DBG_VPI) printf("rsp-rtl_sim: dbg_ctrl_read: 0x%.8x\n",resp); |
|
398,7 → 423,7
|
send_address_to_vpi(adr); |
|
get_data_from_vpi(data); |
get_word_from_vpi(data); |
|
get_response_from_vpi(); |
|
405,6 → 430,24
return 0; |
} |
|
/* read a word from wishbone */ |
int dbg_wb_read8(uint32_t adr, uint8_t *data) |
{ |
if (DBG_CALLS)printf("dbg_wb_read8: adr 0x%.8x \n",adr); |
|
dbg_set_chain(DC_WISHBONE); |
|
send_command_to_vpi(CMD_WB_RD8); |
|
send_address_to_vpi(adr); |
|
get_byte_from_vpi(data); |
|
get_response_from_vpi(); |
|
return 0; |
} |
|
/* write a word to wishbone */ |
int dbg_wb_write32(uint32_t adr, uint32_t data) |
{ |
527,7 → 570,7
|
send_data_to_vpi(length); // Added 090901 --jb |
|
get_block_data_from_vpi(length, data); // changed 090901 --jb //get_data_from_vpi(data); |
get_block_data_from_vpi(length, data); // changed 090901 --jb //get_word_from_vpi(data); |
|
get_response_from_vpi(); |
|
/vpi/c/Makefile
45,10 → 45,40
|
#DEBUG_DEFINES=-DDEBUG -DDEBUG2 -DDEBUG_ON=1 -DDEBUG_GDB=1 -DDEBUG_CMDS=1 |
|
# Due to a difference in the type for a memory array passed back to the VPI |
# interface, we must indicate whether we're compiling the jp_vpi module for use |
# with Modelsim or with Icarus. We do this via defines passed at compile time, |
# -DSIMULATOR_VPI |
|
# Set V=1 when calling make to enable verbose output |
# mainly for debugging purposes. |
ifeq ($(V), 1) |
Q= |
QUIET= |
else |
Q ?=@ |
QUIET=-quiet |
endif |
|
all: jp_vpi |
|
jp_vpi: $(SOURCE_FILES) |
iverilog-vpi $(SOURCE_FILES) $(DEBUG_DEFINES) |
iverilog-vpi $(SOURCE_FILES) $(DEBUG_DEFINES) -DICARUS_VPI |
|
SOURCE_FILES= jp_vpi.c rsp-rtl_sim.c gdb.c |
OBJ_FILES= jp_vpi.o rsp-rtl_sim.o gdb.o |
|
MODELTECH_INC_PATH=$(MGC_PATH)/modeltech/include |
# Modelsim VPI compile commands |
msim_jp_vpi.sl: $(OBJ_FILES) |
ld -shared -E -o $@ $? |
%.o: %.c |
$(Q)echo; echo "\t### Building VPI debug components for Modelsim ###"; echo; |
$(Q)gcc -g ${DEBUG_DEFINES} -I${MODELTECH_INC_PATH} \ |
-l${MODELTECH_INC_PATH} \ |
-DMODELSIM_VPI \ |
-c $< -o $*.o |
|
clean: |
rm -f *.o *~ jp_vpi.vpi |
$(Q)echo; echo "\t### Cleaning VPI debug directory ###"; echo; |
$(Q)rm -f *.o *~ jp_vpi.vpi msim_jp_vpi.sl |
/vpi/c/gdb.c
144,6 → 144,7
string. So at least NUMREGBYTES*2 + 1 (for the 'G' or the EOS) are needed |
for register packets */ |
#define GDB_BUF_MAX ((NUM_REGS) * 8 + 1) |
#define GDB_BUF_MAX_TIMES_TWO (GDB_BUF_MAX*2) |
//#define GDB_BUF_MAX 1500 |
|
/*! Size of the matchpoint hash table. Largest prime < 2^10 */ |
424,6 → 425,7
static int gdb_write_byte(uint32_t adr, uint8_t data); |
static int gdb_write_short(uint32_t adr, uint16_t data); |
static int gdb_write_reg(uint32_t adr, uint32_t data); |
static int gdb_read_byte(uint32_t adr, uint8_t *data); |
static int gdb_read_reg(uint32_t adr, uint32_t *data); |
static int gdb_write_block(uint32_t adr, uint32_t *data, int len); |
static int gdb_read_block(uint32_t adr, uint32_t *data, int len); |
2214,6 → 2216,7
int len_cpy; |
/* Couple of temps we might need when doing aligning/leftover accesses */ |
uint32_t tmp_word; |
uint8_t tmp_byte; |
char *tmp_word_ptr = (char*) &tmp_word; |
|
|
2227,6 → 2230,149
} |
|
/* Make sure we won't overflow the buffer (2 chars per byte) */ |
if ((len * 2) >= GDB_BUF_MAX_TIMES_TWO) |
{ |
fprintf (stderr, "Warning: Memory read %s too large for RSP packet: " |
"truncated\n", p_buf->data); |
len = (GDB_BUF_MAX - 1) / 2; |
} |
|
if(!(rec_buf = (char*)malloc(len))) { |
put_str_packet ("E01"); |
return; |
} |
|
// Make sure the processor is stalled |
gdb_ensure_or1k_stalled(); |
|
// Set chain 5 --> Wishbone Memory chain |
err = gdb_set_chain(SC_WISHBONE); |
if(err){ |
if (DEBUG_GDB) printf("Error %d in gdb_set_chain\n", err); |
put_str_packet ("E01"); |
return; |
} |
|
len_cpy = len; |
rec_buf_ptr = rec_buf; // Need to save a copy of pointer |
|
if (addr & 0x3) // address not word-aligned, do byte accesses first |
{ |
|
int num_bytes_to_align = bytes_per_word - (addr & 0x3); |
|
int bytes_to_read = (num_bytes_to_align >= len_cpy) ? |
len_cpy : num_bytes_to_align; |
|
for (i=0;i<bytes_to_read;i++) |
{ |
err = gdb_read_byte(addr++, (uint8_t*) &rec_buf[i]); |
if(err){ |
put_str_packet ("E01"); |
return; |
} |
} |
|
// Adjust our status |
len_cpy -= bytes_to_read; |
rec_buf_ptr += num_bytes_to_align; |
} |
|
if (len_cpy/bytes_per_word) // Now perform all full word accesses |
{ |
int words_to_read = len_cpy/bytes_per_word; // Full words to read |
if (DEBUG_GDB) printf("rsp_read_mem: reading %d words from 0x%.8x\n", |
words_to_read, addr); |
// Read full data words from Wishbone Memory chain |
err = gdb_read_block(addr, (uint32_t*)rec_buf_ptr, |
words_to_read*bytes_per_word); |
|
if(err){ |
put_str_packet ("E01"); |
return; |
} |
|
// Adjust our status |
len_cpy -= (words_to_read*bytes_per_word); |
addr += (words_to_read*bytes_per_word); |
rec_buf_ptr += (words_to_read*bytes_per_word); |
} |
if (len_cpy) // Leftover bytes |
{ |
for (i=0;i<len_cpy;i++) |
{ |
err = gdb_read_byte(addr++, (uint8_t*) &rec_buf_ptr[i]); |
if(err){ |
put_str_packet ("E01"); |
return; |
} |
} |
|
} |
|
/* Refill the buffer with the reply */ |
for( off = 0 ; off < len ; off ++ ) { |
; |
p_buf->data[(2*off)] = hexchars[((rec_buf[off]&0xf0)>>4)]; |
p_buf->data[(2*off)+1] = hexchars[(rec_buf[off]&0x0f)]; |
} |
|
if (DEBUG_GDB && (err > 0)) printf("\nError %x\n", err);fflush (stdout); |
free(rec_buf); |
p_buf->data[off * 2] = 0; /* End of string */ |
p_buf->len = strlen (p_buf->data); |
if (DEBUG_GDB_BLOCK_DATA){ |
printf("rsp_read_mem: adr 0x%.8x data: ", addr); |
for(i=0;i<len*2;i++) |
printf("%c",p_buf->data[i]); |
printf("\n"); |
} |
|
put_packet (p_buf); |
|
} /* rsp_read_mem () */ |
#if 0 |
/*---------------------------------------------------------------------------*/ |
/* Handle a RSP read memory (symbolic) request |
|
Syntax is: |
|
m<addr>,<length>: |
|
The response is the bytes, lowest address first, encoded as pairs of hex |
digits. |
|
The length given is the number of bytes to be read. |
|
@note This function reuses p_buf, so trashes the original command. |
|
@param[in] p_buf The command received */ |
/*---------------------------------------------------------------------------*/ |
static void rsp_read_mem (struct rsp_buf *p_buf) |
{ |
unsigned int addr; /* Where to read the memory */ |
int len; /* Number of bytes to read */ |
int off; /* Offset into the memory */ |
uint32_t temp_uint32 = 0; |
char *rec_buf, *rec_buf_ptr; |
int bytes_per_word = 4; /* Current OR implementation is 4-byte words */ |
int i; |
int len_cpy; |
/* Couple of temps we might need when doing aligning/leftover accesses */ |
uint32_t tmp_word; |
char *tmp_word_ptr = (char*) &tmp_word; |
|
|
|
if (2 != sscanf (p_buf->data, "m%x,%x:", &addr, &len)) |
{ |
fprintf (stderr, "Warning: Failed to recognize RSP read memory " |
"command: %s\n", p_buf->data); |
put_str_packet ("E01"); |
return; |
} |
|
/* Make sure we won't overflow the buffer (2 chars per byte) */ |
if ((len * 2) >= GDB_BUF_MAX) |
{ |
fprintf (stderr, "Warning: Memory read %s too large for RSP packet: " |
2353,7 → 2499,7
return; |
} |
|
/* Refill the buffer with the reply */ |
// Refill the buffer with the reply |
for( off = 0 ; off < len ; off ++ ) { |
; |
p_buf->data[(2*off)] = hexchars[((rec_buf[off]&0xf0)>>4)]; |
2373,8 → 2519,8
|
put_packet (p_buf); |
} /* rsp_read_mem () */ |
#endif |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Handle a RSP write memory (symbolic) request ("M") |
|
3840,6 → 3986,17
} |
|
|
int gdb_read_byte(uint32_t adr, uint8_t *data) { |
if (DEBUG_CMDS) printf("rreg %d\n", gdb_chain); |
switch (gdb_chain) { |
case SC_RISC_DEBUG: *data = 0; return 0; // Should probably throw an error for chains without byte read... |
case SC_REGISTER: *data = 0; return 0; |
case SC_WISHBONE: return dbg_wb_read8(adr, data) ? ERR_CRC : ERR_NONE; |
case SC_TRACE: *data = 0; return 0; |
default: return JTAG_PROXY_INVALID_CHAIN; |
} |
} |
|
int gdb_read_reg(uint32_t adr, uint32_t *data) { |
if (DEBUG_CMDS) printf("rreg %d\n", gdb_chain); |
switch (gdb_chain) { |
/vpi/verilog/vpi_debug_defines.v
198,7 → 198,7
`define CMD_RESET 4'hb |
`define CMD_READ_JTAG_ID 4'hc |
`define CMD_GDB_DETACH 4'hd |
|
`define CMD_WB_RD8 4'he /* Byte read is useful with a system with byte peripherals! */ |
// commands: |
// 4'h1 jtag set instruction register (input: instruction value) |
// 4'h2 set debug chain (dbg_set_command here) (input: chain value) |
/vpi/verilog/vpi_debug_module.v
58,6 → 58,7
reg tdi; |
|
reg [31:0] in_data_le, in_data_be; |
reg [31:0] incoming_word; |
reg err; |
integer i; |
|
114,7 → 115,7
// (this is around 20k ns if the flash_crash boot code |
// is being booted from, else much bigger, around 10mil ns) |
|
#200_000 main; |
#2_000 main; |
|
end |
|
193,7 → 194,7
|
debug_cpu_rd_ctrl(cpu_ctrl_val); |
|
$return_command_data(cpu_ctrl_val); |
$return_command_data(4,cpu_ctrl_val); |
|
end |
|
287,9 → 288,20
|
wb_read_32(cmd_data, cmd_adr, 16'h3); |
|
$return_command_data(cmd_data); |
$return_command_data(4,cmd_data); |
|
end |
|
`CMD_WB_RD8 : |
begin |
|
$get_command_address(cmd_adr); |
|
wb_read_8(cmd_data, cmd_adr, 16'h0); |
|
$return_command_data(1,cmd_data); |
|
end |
|
`CMD_WB_BLOCK_WR32 : |
begin |
322,7 → 334,7
|
read_id_code(id); |
|
$return_command_data(id); |
$return_command_data(4,id); |
|
end |
|
329,7 → 341,7
`CMD_GDB_DETACH : |
begin |
|
$display("Debugging client disconnected. Finishing simulation"); |
$display("(%t)(%m)Debugging client disconnected. Finishing simulation", $time); |
|
|
$finish(); |
694,9 → 706,27
if (length>3) |
$display("WARNING: Only first data word is stored for writting ( See module %m)"); |
end |
endtask |
endtask // wb_read_32 |
|
// 8-bit read from the wishbone |
task wb_read_8; |
|
output [31:0] data; |
|
input [`DBG_WB_ADR_LEN -1:0] addr; |
input [`DBG_WB_LEN_LEN -1:0] length; |
|
begin |
debug_wishbone_wr_comm(`DBG_WB_READ8, addr, length, 1'b0); |
last_wb_cmd = `DBG_WB_READ8; last_wb_cmd_text = "DBG_WB_READ8"; |
length_global = length + 1; |
debug_wishbone_go(1'b1, 1'b0); |
data = data_storage[0]; |
end |
endtask // wb_read_8 |
|
|
|
// block 32-bit read from the wishbone |
// assumes data will be stored into data_storage[] |
task wb_block_read_32; |
991,16 → 1021,27
|
gen_clk(1); |
|
if (i[4:0] == 31) // Latching data |
if (i[2:0] == 7) // Latching data |
incoming_word = {incoming_word[23:0],in_data_be[7:0]}; |
|
if (i[4:0] == 31) |
begin |
|
data_storage[word_pointer] = in_data_be; |
data_storage[word_pointer] = incoming_word; |
`ifdef DEBUG_INFO |
$display("\t\tin_data_be = 0x%x", in_data_be); |
$display("\t\tin_data_be = 0x%x", incoming_word); |
`endif |
word_pointer = word_pointer + 1; |
|
end |
end // for (i=0; i<(length_global<<3); i=i+1) |
|
// Copy in any leftovers |
if (length_global[1:0] != 0) |
begin |
data_storage[word_pointer] = incoming_word; |
`ifdef DEBUG_INFO |
$display("\t\tin_data_be = 0x%x", incoming_word); |
`endif |
end |
end |
|