141 lines
2.5 KiB
Verilog
141 lines
2.5 KiB
Verilog
`timescale 1 ns / 1 ps
|
|
|
|
`ifndef VERILATOR
|
|
module testbench #(
|
|
parameter VERBOSE = 0
|
|
);
|
|
reg clk = 1;
|
|
reg resetn = 1;
|
|
wire trap;
|
|
|
|
always #5 clk = ~clk;
|
|
|
|
initial begin
|
|
repeat (100) @(posedge clk);
|
|
resetn <= 0;
|
|
end
|
|
|
|
initial begin
|
|
if ($test$plusargs("vcd")) begin
|
|
$dumpfile("testbench.vcd");
|
|
$dumpvars(0, testbench);
|
|
end
|
|
repeat (1000000) @(posedge clk);
|
|
$display("TIMEOUT");
|
|
$finish;
|
|
end
|
|
|
|
wire trace_valid;
|
|
wire [35:0] trace_data;
|
|
integer trace_file;
|
|
|
|
initial begin
|
|
if ($test$plusargs("trace")) begin
|
|
trace_file = $fopen("testbench.trace", "w");
|
|
repeat (10) @(posedge clk);
|
|
while (!trap) begin
|
|
@(posedge clk);
|
|
if (trace_valid)
|
|
$fwrite(trace_file, "%x\n", trace_data);
|
|
end
|
|
$fclose(trace_file);
|
|
$display("Finished writing testbench.trace.");
|
|
end
|
|
end
|
|
|
|
picorv32_wrapper #(
|
|
.VERBOSE (VERBOSE)
|
|
) top (
|
|
.wb_clk(clk),
|
|
.wb_rst(resetn),
|
|
.trap(trap),
|
|
.trace_valid(trace_valid),
|
|
.trace_data(trace_data)
|
|
);
|
|
endmodule
|
|
`endif
|
|
|
|
module picorv32_wrapper #(
|
|
parameter VERBOSE = 0
|
|
) (
|
|
input wb_clk,
|
|
input wb_rst,
|
|
output trap,
|
|
output trace_valid,
|
|
output [35:0] trace_data
|
|
);
|
|
wire exit;
|
|
reg [31:0] irq = 0;
|
|
wire mem_instr;
|
|
|
|
reg [15:0] count_cycle = 0;
|
|
always @(posedge wb_clk) count_cycle <= !wb_rst ? count_cycle + 1 : 0;
|
|
|
|
always @* begin
|
|
irq = 0;
|
|
irq[4] = &count_cycle[12:0];
|
|
irq[5] = &count_cycle[15:0];
|
|
end
|
|
|
|
wire [31:0] wb_m2s_adr;
|
|
wire [31:0] wb_m2s_dat;
|
|
wire [3:0] wb_m2s_sel;
|
|
wire wb_m2s_we;
|
|
wire wb_m2s_cyc;
|
|
wire wb_m2s_stb;
|
|
wire [31:0] wb_s2m_dat;
|
|
wire wb_s2m_ack;
|
|
|
|
picorv32_wb #(
|
|
`ifndef SYNTH_TEST
|
|
`ifdef SP_TEST
|
|
.ENABLE_REGS_DUALPORT(0),
|
|
`endif
|
|
`ifdef COMPRESSED_ISA
|
|
.COMPRESSED_ISA(1),
|
|
`endif
|
|
.ENABLE_MUL(1),
|
|
.ENABLE_DIV(1),
|
|
.ENABLE_IRQ(1),
|
|
.ENABLE_TRACE(1)
|
|
`endif
|
|
) uut (
|
|
.trap (trap),
|
|
.exit(exit),
|
|
.irq (irq),
|
|
.trace_valid (trace_valid),
|
|
.trace_data (trace_data),
|
|
.mem_instr(mem_instr),
|
|
|
|
.wb_clk_i(wb_clk),
|
|
.wb_rst_i(wb_rst),
|
|
);
|
|
|
|
reg [1023:0] firmware_file;
|
|
initial begin
|
|
if (!$value$plusargs("firmware=%s", firmware_file))
|
|
firmware_file = "firmware/firmware.hex";
|
|
$readmemh(firmware_file, uut.memory);
|
|
end
|
|
|
|
integer cycle_counter;
|
|
always @(posedge wb_clk) begin
|
|
cycle_counter <= !wb_rst ? cycle_counter + 1 : 0;
|
|
if (!wb_rst && trap) begin
|
|
`ifndef VERILATOR
|
|
repeat (10) @(posedge wb_clk);
|
|
`endif
|
|
$display("TRAP after %1d clock cycles", cycle_counter);
|
|
if (exit) begin
|
|
$display("ALL TESTS PASSED.");
|
|
$finish;
|
|
end else begin
|
|
$display("ERROR!");
|
|
if ($test$plusargs("noerror"))
|
|
$finish;
|
|
$stop;
|
|
end
|
|
end
|
|
end
|
|
endmodule
|