blob: 7883ed86966758352a379a64fb7ab213553ec356 [file] [log] [blame]
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2021 Tamas Hubai
`default_nettype none
module cpu_core_tb();
parameter DATA_WIDTH = 16;
parameter PC_WIDTH = 8;
parameter ADDR_WIDTH = 8;
parameter SPREAD_WIDTH = 2;
parameter INSTR_WIDTH = 32;
reg clk;
reg rst_n;
wire [INSTR_WIDTH-1:0] opcode;
wire [PC_WIDTH-1:0] progctr;
wire mem_we;
wire [ADDR_WIDTH-1:0] mem_waddr;
wire [SPREAD_WIDTH-1:0] mem_wspread;
wire [DATA_WIDTH-1:0] mem_wdata;
wire [ADDR_WIDTH-1:0] mem_raddr;
wire [DATA_WIDTH-1:0] mem_rdata;
wire debug_stopped;
wire [DATA_WIDTH-1:0] debug_rdata;
cpu_core #(
.DATA_WIDTH(DATA_WIDTH),
.PC_WIDTH(PC_WIDTH),
.ADDR_WIDTH(ADDR_WIDTH),
.SPREAD_WIDTH(SPREAD_WIDTH),
.INSTR_WIDTH(INSTR_WIDTH)
) cpu_core_dut (
.clk(clk),
.rst_n(rst_n),
.opcode(opcode),
.mem_rdata(mem_rdata),
.prng_in(16'd0),
.debug_mode(2'd0),
.debug_sel(4'd6),
.debug_we(1'd0),
.debug_wdata(16'd0),
.progctr(progctr),
.mem_we(mem_we),
.mem_waddr(mem_waddr),
.mem_wspread(mem_wspread),
.mem_wdata(mem_wdata),
.mem_raddr(mem_raddr),
.debug_stopped(debug_stopped),
.debug_rdata(debug_rdata)
);
wire io_dummy_active;
wire [DATA_WIDTH-1:0] io_dummy_data;
mem_mesh #(
.CORES(1),
.DEPTH(16),
.DATA_WIDTH(DATA_WIDTH),
.ADDR_WIDTH(ADDR_WIDTH),
.SPREAD_LAYERS(0),
.SPREAD_WIDTH(SPREAD_WIDTH),
.USE_IO(0),
.IO_PORTS(1),
.IO_FIRST(0)
) mem_mesh_dut (
.clk(clk),
.rst_n(rst_n),
.we(mem_we),
.waddr(mem_waddr),
.wspread(mem_wspread),
.wdata(mem_wdata),
.raddr(mem_raddr),
.rdata(mem_rdata),
.io_dir(1'b1),
.io_active(io_dummy_active),
.io_data(io_dummy_data)
);
always #5 clk = ~clk;
reg [3:0] round;
wire [INSTR_WIDTH-1:0] noop = 32'b000_000_0_00_0000_000_0000000000000000;
wire [INSTR_WIDTH-1:0] progmem ['h100:0];
localparam n_tests = 4;
// test 1
assign progmem['h00] = 32'b100_000_1_00_0011_001_0000000001001001; // reg1 = 73
assign progmem['h01] = 32'b100_000_1_00_0011_010_0000000001001010; // reg2 = 74
assign progmem['h02] = 32'b000_001_1_00_1010_011_0000000000000000; // jmp reg1 + reg2
// test 2
assign progmem['h10] = 32'b100_000_1_00_0011_001_0000000011110011; // reg1 = 243
assign progmem['h11] = 32'b000_000_1_11_0011_111_0000000000010000; // mem[1] = reg1
assign progmem['h12] = 32'b100_000_1_00_0011_100_0000000000000000; // t = mem[0]
assign progmem['h13] = 32'b011_111_1_11_1010_111_0000000000000000; // mem[0] = t+1
assign progmem['h14] = 32'b100_000_1_00_0011_100_0000000000000000; // t = mem[0]
assign progmem['h15] = 32'b011_000_1_00_0011_100_0000000000000000; // t = mem[t]
assign progmem['h16] = 32'b011_000_1_00_0011_011_0000000000000000; // jmp t
// test 3
assign progmem['h20] = 32'b110_100_1_00_1011_001_0000000000010111; // reg1 = timer - 23
assign progmem['h21] = 32'b000_010_1_01_0011_011_0000000000000000; // jmp (reg1 < 0) ? 0 : pc
assign progmem['h22] = 32'b100_000_1_00_0011_011_0000000000101100; // jmp 44
// test 4
assign progmem['h30] = 32'b100_000_1_00_0011_010_0000000010001000; // reg2 = 136
assign progmem['h31] = 32'b001_000_1_11_0011_111_0000000000100000; // mem[2] = reg2
assign progmem['h32] = 32'b100_000_1_00_0011_100_0000000000000010; // t = mem[2]
assign progmem['h33] = 32'b100_000_1_10_0011_010_0000000000010001; // reg1 = t; reg2 = 17
assign progmem['h34] = 32'b000_001_1_00_1010_011_0000000000000000; // jmp reg1 + reg2
assign opcode = rst_n ? (progctr < 16 ? progmem[round << 4 | progctr] : noop) : noop;
always @ (posedge clk) begin
if (progctr >= 16) begin
rst_n = 0;
if (round + 1 >= n_tests) $finish;
round = round + 1;
$display("");
#12 rst_n = 1;
end
end
initial begin
$monitor("time=%4t round=%1x rstn=%1b ct=%2d op=%32b new_pc=%8b(%2x) reg1=%16b we=%1b wa=%8b ws=%2b wd=%16b ra=%8b rd=%16b dd=%16b",
$time, round, rst_n, cpu_core_dut.timer, opcode, progctr, progctr, cpu_core_dut.reg1,
mem_we, mem_waddr, mem_wspread, mem_wdata, mem_raddr, mem_rdata, debug_rdata);
round = 0;
clk = 0;
rst_n = 0;
#12 rst_n = 1;
end
endmodule
`default_nettype wire