blob: 26b7ccffb6ab28ed94b5e80077876873f983d882 [file] [log] [blame] [edit]
module testbench;
// Generic Inputs
reg clk;
reg i_irq; // Interrupt request, active high
reg i_firq; // Fast Interrupt request, active high
reg i_system_rdy; // Amber is stalled when this is low
reg globrst;
// Wishbone Inputs
reg [31:0] i_wb_dat;
wire i_wb_ack;
wire i_wb_err;
// Wishbone Outputs
wire [31:0] o_wb_adr;
wire [ 3:0] o_wb_sel;
wire o_wb_we;
wire [31:0] o_wb_dat;
wire o_wb_cyc;
wire o_wb_stb;
`ifdef A23_BIT_PORTS
// Instructions for simulating ABC output:
//
// Execute all commands in ../rtl/ directory
// Copy files 'amber23.ys' and 'adff2dff.v' from Yosys AppNote 010
//
// yosys amber23.ys
// abc -c 'read_blif amber23.blif; strash -v; balance -v; refactor -v; write_verilog amber23.v'
//
// MODELSIM_DIR=/opt/altera/13.1/modelsim_ase
// $MODELSIM_DIR/bin/vlib work
// $MODELSIM_DIR/bin/vlog amber23.v
// $MODELSIM_DIR/bin/vlog +incdir+../sim +define+A23_BIT_PORTS ../sim/bench.v
// $MODELSIM_DIR/bin/vsim -c -do "run -all; exit" work.testbench
a23_core UUT (
.\clock ( clk ),
.\i_clk ( clk ),
.\i_irq ( i_irq ),
.\i_firq ( i_firq ),
.\i_system_rdy ( i_system_rdy ),
.\o_wb_adr[0] ( o_wb_adr[0] ),
.\o_wb_adr[1] ( o_wb_adr[1] ),
.\o_wb_adr[2] ( o_wb_adr[2] ),
.\o_wb_adr[3] ( o_wb_adr[3] ),
.\o_wb_adr[4] ( o_wb_adr[4] ),
.\o_wb_adr[5] ( o_wb_adr[5] ),
.\o_wb_adr[6] ( o_wb_adr[6] ),
.\o_wb_adr[7] ( o_wb_adr[7] ),
.\o_wb_adr[8] ( o_wb_adr[8] ),
.\o_wb_adr[9] ( o_wb_adr[9] ),
.\o_wb_adr[10] ( o_wb_adr[10] ),
.\o_wb_adr[11] ( o_wb_adr[11] ),
.\o_wb_adr[12] ( o_wb_adr[12] ),
.\o_wb_adr[13] ( o_wb_adr[13] ),
.\o_wb_adr[14] ( o_wb_adr[14] ),
.\o_wb_adr[15] ( o_wb_adr[15] ),
.\o_wb_adr[16] ( o_wb_adr[16] ),
.\o_wb_adr[17] ( o_wb_adr[17] ),
.\o_wb_adr[18] ( o_wb_adr[18] ),
.\o_wb_adr[19] ( o_wb_adr[19] ),
.\o_wb_adr[20] ( o_wb_adr[20] ),
.\o_wb_adr[21] ( o_wb_adr[21] ),
.\o_wb_adr[22] ( o_wb_adr[22] ),
.\o_wb_adr[23] ( o_wb_adr[23] ),
.\o_wb_adr[24] ( o_wb_adr[24] ),
.\o_wb_adr[25] ( o_wb_adr[25] ),
.\o_wb_adr[26] ( o_wb_adr[26] ),
.\o_wb_adr[27] ( o_wb_adr[27] ),
.\o_wb_adr[28] ( o_wb_adr[28] ),
.\o_wb_adr[29] ( o_wb_adr[29] ),
.\o_wb_adr[30] ( o_wb_adr[30] ),
.\o_wb_adr[31] ( o_wb_adr[31] ),
.\o_wb_sel[0] ( o_wb_sel[0] ),
.\o_wb_sel[1] ( o_wb_sel[1] ),
.\o_wb_sel[2] ( o_wb_sel[2] ),
.\o_wb_sel[3] ( o_wb_sel[3] ),
.\o_wb_we ( o_wb_we ),
.\i_wb_dat[0] ( i_wb_dat[0] ),
.\i_wb_dat[1] ( i_wb_dat[1] ),
.\i_wb_dat[2] ( i_wb_dat[2] ),
.\i_wb_dat[3] ( i_wb_dat[3] ),
.\i_wb_dat[4] ( i_wb_dat[4] ),
.\i_wb_dat[5] ( i_wb_dat[5] ),
.\i_wb_dat[6] ( i_wb_dat[6] ),
.\i_wb_dat[7] ( i_wb_dat[7] ),
.\i_wb_dat[8] ( i_wb_dat[8] ),
.\i_wb_dat[9] ( i_wb_dat[9] ),
.\i_wb_dat[10] ( i_wb_dat[10] ),
.\i_wb_dat[11] ( i_wb_dat[11] ),
.\i_wb_dat[12] ( i_wb_dat[12] ),
.\i_wb_dat[13] ( i_wb_dat[13] ),
.\i_wb_dat[14] ( i_wb_dat[14] ),
.\i_wb_dat[15] ( i_wb_dat[15] ),
.\i_wb_dat[16] ( i_wb_dat[16] ),
.\i_wb_dat[17] ( i_wb_dat[17] ),
.\i_wb_dat[18] ( i_wb_dat[18] ),
.\i_wb_dat[19] ( i_wb_dat[19] ),
.\i_wb_dat[20] ( i_wb_dat[20] ),
.\i_wb_dat[21] ( i_wb_dat[21] ),
.\i_wb_dat[22] ( i_wb_dat[22] ),
.\i_wb_dat[23] ( i_wb_dat[23] ),
.\i_wb_dat[24] ( i_wb_dat[24] ),
.\i_wb_dat[25] ( i_wb_dat[25] ),
.\i_wb_dat[26] ( i_wb_dat[26] ),
.\i_wb_dat[27] ( i_wb_dat[27] ),
.\i_wb_dat[28] ( i_wb_dat[28] ),
.\i_wb_dat[29] ( i_wb_dat[29] ),
.\i_wb_dat[30] ( i_wb_dat[30] ),
.\i_wb_dat[31] ( i_wb_dat[31] ),
.\o_wb_dat[0] ( o_wb_dat[0] ),
.\o_wb_dat[1] ( o_wb_dat[1] ),
.\o_wb_dat[2] ( o_wb_dat[2] ),
.\o_wb_dat[3] ( o_wb_dat[3] ),
.\o_wb_dat[4] ( o_wb_dat[4] ),
.\o_wb_dat[5] ( o_wb_dat[5] ),
.\o_wb_dat[6] ( o_wb_dat[6] ),
.\o_wb_dat[7] ( o_wb_dat[7] ),
.\o_wb_dat[8] ( o_wb_dat[8] ),
.\o_wb_dat[9] ( o_wb_dat[9] ),
.\o_wb_dat[10] ( o_wb_dat[10] ),
.\o_wb_dat[11] ( o_wb_dat[11] ),
.\o_wb_dat[12] ( o_wb_dat[12] ),
.\o_wb_dat[13] ( o_wb_dat[13] ),
.\o_wb_dat[14] ( o_wb_dat[14] ),
.\o_wb_dat[15] ( o_wb_dat[15] ),
.\o_wb_dat[16] ( o_wb_dat[16] ),
.\o_wb_dat[17] ( o_wb_dat[17] ),
.\o_wb_dat[18] ( o_wb_dat[18] ),
.\o_wb_dat[19] ( o_wb_dat[19] ),
.\o_wb_dat[20] ( o_wb_dat[20] ),
.\o_wb_dat[21] ( o_wb_dat[21] ),
.\o_wb_dat[22] ( o_wb_dat[22] ),
.\o_wb_dat[23] ( o_wb_dat[23] ),
.\o_wb_dat[24] ( o_wb_dat[24] ),
.\o_wb_dat[25] ( o_wb_dat[25] ),
.\o_wb_dat[26] ( o_wb_dat[26] ),
.\o_wb_dat[27] ( o_wb_dat[27] ),
.\o_wb_dat[28] ( o_wb_dat[28] ),
.\o_wb_dat[29] ( o_wb_dat[29] ),
.\o_wb_dat[30] ( o_wb_dat[30] ),
.\o_wb_dat[31] ( o_wb_dat[31] ),
.\o_wb_cyc ( o_wb_cyc ),
.\o_wb_stb ( o_wb_stb ),
.\i_wb_ack ( i_wb_ack ),
.\i_wb_err ( i_wb_err ),
.\globrst ( globrst )
);
`else
a23_core UUT (
clk,
i_irq,
i_firq,
i_system_rdy,
o_wb_adr,
o_wb_sel,
o_wb_we,
i_wb_dat,
o_wb_dat,
o_wb_cyc,
o_wb_stb,
i_wb_ack,
i_wb_err,
globrst
);
`endif
initial begin
clk <= 0;
#100;
forever begin
clk <= ~clk;
#50;
end
end
initial begin
i_irq <= 0;
i_firq <= 0;
i_wb_dat <= 0;
i_system_rdy <= 0;
globrst <= 0;
repeat (5) @(posedge clk);
globrst <= 1;
repeat (2) @(posedge clk);
globrst <= 0;
repeat (3) @(posedge clk);
i_system_rdy <= 1;
repeat (5000) @(posedge clk);
$display("Reached limit of 5000 cpu cycles.");
$finish;
end
integer output_idx;
reg [7:0] output_buf [1023:0];
event output_eof;
localparam mem_size = 16*1024; // = 64kB
reg [31:0] mem [0:mem_size-1];
reg [31:0] tmp;
integer i;
initial begin
output_idx = 0;
for (i=0; i<mem_size; i=i+1)
mem[i] = 0;
`include "sieve.vh"
end
reg wb_start_read_d1;
wire wb_start_write = o_wb_stb && o_wb_we && !wb_start_read_d1;
wire wb_start_read = o_wb_stb && !o_wb_we && !i_wb_ack;
assign i_wb_ack = o_wb_stb && ( wb_start_write || wb_start_read_d1 );
assign i_wb_err = 0;
always @(posedge clk)
wb_start_read_d1 <= wb_start_read;
always @(posedge clk) begin
if (wb_start_write || wb_start_read) begin
if (o_wb_adr < mem_size*4) begin
tmp = mem[o_wb_adr >> 2];
if (wb_start_write) begin
if (o_wb_sel[0]) tmp = { tmp[31:24], tmp[23:16], tmp[15:8], o_wb_dat[7:0] };
if (o_wb_sel[1]) tmp = { tmp[31:24], tmp[23:16], o_wb_dat[15:8], tmp[7:0] };
if (o_wb_sel[2]) tmp = { tmp[31:24], o_wb_dat[23:16], tmp[15:8], tmp[7:0] };
if (o_wb_sel[3]) tmp = { o_wb_dat[31:24], tmp[23:16], tmp[15:8], tmp[7:0] };
mem[o_wb_adr >> 2] <= tmp;
end
if (wb_start_read)
i_wb_dat <= tmp;
$display("%t MEM %s ADDR %08x: %08x (%b)", $time, o_wb_we ? "WRITE" : "READ ", o_wb_adr, tmp, o_wb_sel);
end
if (wb_start_write && o_wb_adr == 32'h10000000) begin
$display("%t OUTPUT %d", $time, o_wb_dat);
if (o_wb_dat == 0) begin
-> output_eof;
end else begin
output_buf[output_idx] = o_wb_dat;
output_idx = output_idx + 1;
end
end
end
end
always @(output_eof) begin
#1001;
$display("Got EOF marker on IO port.");
for (i = 0; i < output_idx; i = i + 1) begin
$display("+OUT+ %d", output_buf[i]);
end
$finish;
end
initial begin
// $dumpfile("bench.vcd");
// $dumpvars(0, testbench);
end
endmodule