cpu/testbench/basic_test/tb.sv
2021-08-11 00:18:46 -06:00

231 lines
6.0 KiB
Systemverilog

`timescale 1ns/1ps
module tb();
localparam ADDR_FAILCODE = 32'h800;
localparam WATCHDOG_MAX = 32'h00001000;
initial $timeformat(-9, 2, " ns", 20);
initial begin: dump
integer i;
$dumpfile("tb.vcd");
$dumpvars(0, tb);
for (i=0; i<32; i=i+1) begin
$dumpvars(0, dut.regfile[i]);
end
$dumpvars(0, mem[ADDR_FAILCODE]);
end
reg clk, reset;
wire dummy_out;
// Memory Parameters
localparam MEM_ROM_LENGTH = 2048; // bytes
localparam MEM_LENGTH = MEM_ROM_LENGTH + 2048; // bytes
localparam DATA_INVALID = 32'hdeadbeef;
// Memory
reg [7:0] mem [0:MEM_LENGTH-1];
initial $readmemh("tb.hex", mem);
// Instruction Memory
wire [31:0] mem_inst_addr;
reg [31:0] mem_inst_data;
always @(*) begin
if (mem_inst_addr < MEM_LENGTH - 3) begin
mem_inst_data[ 7: 0] = mem[mem_inst_addr+0];
mem_inst_data[15: 8] = mem[mem_inst_addr+1];
mem_inst_data[23:16] = mem[mem_inst_addr+2];
mem_inst_data[31:24] = mem[mem_inst_addr+3];
end else begin
mem_inst_data = DATA_INVALID;
end
end
// Data memory
wire [31:0] mem_data_addr;
reg [31:0] mem_data_rdata;
wire [31:0] mem_data_wdata;
wire [3:0] mem_data_wmask;
wire mem_data_we;
reg mem_data_wready;
reg mem_data_rvalid;
always @(mem_data_addr) begin
mem_data_rvalid = 1'b1;
if (mem_data_addr < MEM_LENGTH - 3) begin
mem_data_rdata[ 7: 0] = mem[mem_data_addr+0];
if (mem_data_addr[0] == 0) begin
mem_data_rdata[15: 8] = mem[mem_data_addr+1];
if (mem_data_addr[1] == 0) begin
mem_data_rdata[23:16] = mem[mem_data_addr+2];
mem_data_rdata[31:24] = mem[mem_data_addr+3];
end else begin
mem_data_rdata[31:16] = 0;
end
end else begin
mem_data_rdata[31:8] = 0;
end
end else begin
mem_data_rdata = DATA_INVALID;
end
end
always @(posedge clk) begin
if (mem_data_we) begin
if (mem_data_wready) begin
mem_data_wready = 1'b0;
if (mem_data_addr < MEM_LENGTH && mem_data_addr >= MEM_ROM_LENGTH) begin
if (mem_data_wmask[0]) begin
mem[mem_data_addr+0] <= mem_data_wdata[7:0];
end
if (mem_data_wmask[1]) begin
mem[mem_data_addr+1] <= mem_data_wdata[15:8];
end
if (mem_data_wmask[2]) begin
mem[mem_data_addr+2] <= mem_data_wdata[23:16];
end
if (mem_data_wmask[3]) begin
mem[mem_data_addr+3] <= mem_data_wdata[31:24];
end
end else begin
// ignore illegal writes
end
end else begin
mem_data_wready = 1'b1;
end
end else begin
mem_data_wready = 1'b0;
end
end
// Main control
initial begin
#0
clk = 0;
reset = 1;
#10
reset = 0;
#10000
reset = 1;
$finish;
end
integer watchdog = 0;
logic [31:0] returnval;
always @(posedge clk) begin
#100
returnval = {mem[ADDR_FAILCODE+3], mem[ADDR_FAILCODE+2], mem[ADDR_FAILCODE+1], mem[ADDR_FAILCODE+0]};
case (returnval)
32'h00000000: begin
// Initial value
end
32'hffffffff: begin
// Success
#100
$display("%0t:\tSUCCESS: TEST PASSED", $time);
$finish;
end
default: begin
$display("%0t:\tERROR: FAILCODE = 0x%h", $time, returnval);
#200
$finish;
end
endcase
watchdog = watchdog + 1;
if (watchdog > WATCHDOG_MAX) begin
$display("%0t:\tERROR: WATCHDOG", $time);
#200
$finish;
end
end
always #2 clk = !clk;
core dut(
.clk(clk),
.reset(reset),
.mem_inst_addr(mem_inst_addr),
.mem_inst_data(mem_inst_data),
.mem_data_addr(mem_data_addr),
.mem_data_rdata(mem_data_rdata),
.mem_data_wdata(mem_data_wdata),
.mem_data_wmask(mem_data_wmask),
.mem_data_we(mem_data_we),
.mem_data_rvalid(mem_data_rvalid),
.mem_data_wready(mem_data_wready),
// .mem_data_addr(mem_data_addr),
// .mem_data_wdata(mem_data_wdata),
// .mem_data_rdata(mem_data_rdata),
// .mem_data_en(mem_data_en),
// .mem_data_we(mem_data_we),
// .mem_data_valid(mem_data_valid),
// .mem_data_done(mem_data_done)
.dummy_out(dummy_out)
);
// wire axi_mem_data_awvalid;
// wire [11:0] axi_mem_data_awaddr;
// wire [2:0] axi_mem_data_awprot;
// wire axi_mem_data_awready;
// wire axi_mem_data_wvalid;
// wire [31:0] axi_mem_data_wdata;
// wire [3:0] axi_mem_data_wstrb;
// wire axi_mem_data_wready;
// wire axi_mem_data_bvalid;
// wire axi_mem_data_bready;
// wire [1:0] axi_mem_data_bresp;
// wire axi_mem_data_arvalid;
// wire [11:0] axi_mem_data_araddr;
// wire [2:0] axi_mem_data_arprot;
// wire axi_mem_data_arready;
// wire axi_mem_data_rvalid;
// wire [31:0] axi_mem_data_rdata;
// wire [1:0] axi_mem_data_resp;
// wire axi_mem_data_rready;
// axi_lite_memory axi_mem_data(
// .ACLK(clk),
// .ARESETn(!reset),
// .AWVALID(axi_mem_data_awvalid),
// .AWADDR(axi_mem_data_awaddr),
// .AWPROT(axi_mem_data_awprot),
// .AWREADY(axi_mem_data_awready),
// .WVALID(axi_mem_data_wvalid),
// .WDATA(axi_mem_data_wdata),
// .WSTRB(axi_mem_data_wstrb),
// .WREADY(axi_mem_data_wready),
// .BVALID(axi_mem_data_bvalid),
// .BREADY(axi_mem_data_bready),
// .BRESP(axi_mem_data_bresp),
// .ARVALID(axi_mem_data_arvalid),
// .ARADDR(axi_mem_data_araddr),
// .ARPROT(axi_mem_data_arprot),
// .ARREADY(axi_mem_data_arready),
// .RVALID(axi_mem_data_rvalid),
// .RDATA(axi_mem_data_rdata),
// .RRESP(axi_mem_data_resp),
// .RREADY(axi_mem_data_rready),
// .WB_WADDR(mem_data_waddr),
// .WB_WPROT(),
// .WB_WDATA(mem_data_wdata),
// .WB_WSTRB(mem_data_wmask),
// .WB_WVALID(mem_data_we),
// .WB_WREADY(1'b1),
// .WB_RADDR(mem_data_raddr),
// .WB_RDATA(mem_data_rdata),
// .WB_RVALID(1'b1),
// .WB_RREADY()
// );
endmodule