Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions rtl/vproc_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ module vproc_top import vproc_pkg::*; #(
input logic mem_rvalid_i,
input logic mem_err_i,
input logic [MEM_W -1:0] mem_rdata_i,
`ifdef VPROC_SIMULATION
output logic uart_we_o,
output logic [7:0] uart_data_o,
`endif

output logic [31:0] pend_vreg_wr_map_o
);
Expand Down Expand Up @@ -710,4 +714,15 @@ module vproc_top import vproc_pkg::*; #(
(imem_req_addr[0][$clog2(MEM_W)-1:0] & {3'b000, {($clog2(MEM_W/8)-2){1'b1}}, 2'b00})*8 +: 32];
assign dmem_rdata = mem_rdata_i;

// Additional UART logic for simulation with caches
// During simulation, we need to read and write from UART
// Since it's a simple simulation, when the status registers of UART never changes
// Then, after setting the initial value correctly, nothing needs to be done
// However, for writes, we need to correctly handle these access as non-cacheable
// Thus, we bypass the cache and send then directly to vproc_tb.sv and verilator_main.cpp
`ifdef VPROC_SIMULATION
assign uart_we_o = data_req & data_we & (data_addr == 32'hFF000000);
assign uart_data_o = data_wdata[7:0]; // only the lowest byte
`endif

endmodule
8 changes: 4 additions & 4 deletions sim/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,19 @@ verilator-version-check:
verilator: verilator-version-check $(PROJ_DIR)/obj_dir/Vvproc_top.mk
make -C $(PROJ_DIR)/obj_dir -f Vvproc_top.mk Vvproc_top; \
$(PROJ_DIR)/obj_dir/Vvproc_top $(abspath $(PROG_PATHS)) $(MEM_W) \
$(MEM_SZ) $(MEM_LATENCY) $$(($(VREG_W) * 2)) $(abspath $(TRACE_FILE)) \
$(MEM_SZ) $(MEM_LATENCY) $$(($(VREG_W) * 2)) $(VREG_W) $(abspath $(TRACE_FILE)) \
$(abspath $(TRACE_VCD)) $(abspath $(TRACE_FST))

$(PROJ_DIR)/obj_dir/Vvproc_top.mk: verilator-version-check $(VPROC_CONFIG_PKG)
cp $(SIM_DIR)/verilator_main.cpp $(PROJ_DIR)/
cd $(PROJ_DIR); \
options=""; \
options="-DVPROC_SIMULATION"; \
cflags=""; \
if [ -n "$(TRACE_VCD)" ]; then \
options="--trace"; \
options="$$options --trace"; \
cflags="-CFLAGS -DTRACE_VCD"; \
elif [ -n "$(TRACE_FST)" ]; then \
options="--trace-fst"; \
options="$$options --trace-fst"; \
cflags="-CFLAGS -DTRACE_FST"; \
fi; \
if [ -n "$(SIM_ABORT_CYCLES)" ]; then \
Expand Down
35 changes: 24 additions & 11 deletions sim/verilator_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ typedef int VerilatedTrace_t;
static void log_cycle(Vvproc_top *top, VerilatedTrace_t *tfp, FILE *fcsv);

int main(int argc, char **argv) {
if (argc != 7 && argc != 8) {
fprintf(stderr, "Usage: %s PROG_PATHS_LIST MEM_W MEM_SZ MEM_LATENCY EXTRA_CYCLES TRACE_FILE [WAVEFORM_FILE]\n", argv[0]);
if (argc != 8 && argc != 9) {
fprintf(stderr, "Usage: %s PROG_PATHS_LIST MEM_W MEM_SZ MEM_LATENCY EXTRA_CYCLES VLEN TRACE_FILE [WAVEFORM_FILE]\n", argv[0]);
return 1;
}

int mem_w, mem_sz, mem_latency, extra_cycles;
int mem_w, mem_sz, mem_latency, extra_cycles, vlen;
{
char *endptr;
mem_w = strtol(argv[2], &endptr, 10);
Expand All @@ -52,6 +52,11 @@ int main(int argc, char **argv) {
fprintf(stderr, "ERROR: invalid EXTRA_CYCLES argument\n");
return 1;
}
vlen = strtol(argv[6], &endptr, 10);
if (*endptr != 0) {
fprintf(stderr, "ERROR: invalid VLEN argument\n");
return 1;
}
}

Verilated::traceEverOn(true);
Expand All @@ -63,9 +68,9 @@ int main(int argc, char **argv) {
return 2;
}

FILE *fcsv = fopen(argv[6], "w");
FILE *fcsv = fopen(argv[7], "w");
if (fcsv == NULL) {
fprintf(stderr, "ERROR: opening `%s': %s\n", argv[6], strerror(errno));
fprintf(stderr, "ERROR: opening `%s': %s\n", argv[7], strerror(errno));
return 2;
}
fprintf(fcsv, "rst_ni;mem_req;mem_addr;pend_vreg_wr_map_o;\n");
Expand All @@ -82,10 +87,10 @@ int main(int argc, char **argv) {
Vvproc_top *top = new Vvproc_top;
VerilatedTrace_t *tfp = NULL;
#if defined(TRACE_VCD) || defined(TRACE_FST)
if (argc == 8) {
if (argc == 9) {
tfp = new VerilatedTrace_t;
top->trace(tfp, 99); // Trace 99 levels of hierarchy
tfp->open(argv[7]);
tfp->open(argv[8]);
}
#endif

Expand Down Expand Up @@ -209,22 +214,30 @@ int main(int argc, char **argv) {
mem_rdata_queue[0] |= ((int64_t)mem[addr+i]) << (i*8);
}
}
// Cache access to the UART
else if (top->mem_req_o) {
// test for memory-mapped registers in case of a request for an invalid addr
switch (addr) {
switch (top->mem_addr_o) {
case 0xFF000000u: // UART data register
valid = true;
mem_rdata_queue[0] = -1; // always reads as -1, i.e. no data received
if (top->mem_we_o) {
putc(top->mem_wdata_o & 0xFF, stdout);
}
break;
case 0xFF000004u: // UART status register
valid = true;
mem_rdata_queue[0] = 0; // always ready to transmit
break;
default:
if((top->mem_addr_o & ~(vlen/8 - 1)) == 0xFF000000u) {
valid = true;
mem_rdata_queue[0] = -1;
}
break;
}
}
// Print bypassed UART data
if (top->uart_we_o) {
putc(top->uart_data_o, stdout);
}
mem_rvalid_queue[0] = top->mem_req_o;
mem_err_queue [0] = !valid;

Expand Down
4 changes: 4 additions & 0 deletions sim/vproc_tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ module vproc_tb #(
logic mem_rvalid;
logic mem_err;
logic [31:0] mem_rdata;
logic uart_we;
logic [7:0] uart_data;

vproc_top #(
.MEM_W ( MEM_W ),
Expand All @@ -52,6 +54,8 @@ module vproc_tb #(
.mem_rvalid_i ( mem_rvalid ),
.mem_err_i ( mem_err ),
.mem_rdata_i ( mem_rdata ),
.uart_we_o ( uart_we ),
.uart_data_o ( uart_data ),
.pend_vreg_wr_map_o ( )
);

Expand Down