mirror of
https://gitlab.com/brendanhaines/cpu.git
synced 2024-11-09 21:14:57 -07:00
134 lines
6.0 KiB
Verilog
134 lines
6.0 KiB
Verilog
`timescale 1 ns / 1 ps
|
|
|
|
module core_tb();
|
|
|
|
localparam MEM_INST_LENGTH = 256;
|
|
localparam MEM_DATA_LENGTH = 256;
|
|
|
|
reg clk, reset;
|
|
wire [31:0] mem_inst_addr;
|
|
wire [31:0] mem_inst_idx = mem_inst_addr >> 2;
|
|
reg [31:0] mem_inst_data;
|
|
reg [31:0] mem_inst [0:MEM_INST_LENGTH-1];
|
|
reg [31:0] mem_data [0:MEM_DATA_LENGTH-1];
|
|
wire [31:0] mem_data_addr;
|
|
wire [31:0] mem_data_wdata;
|
|
reg [31:0] mem_data_rdata;
|
|
wire mem_data_en;
|
|
wire mem_data_we;
|
|
reg mem_data_valid;
|
|
reg mem_data_done;
|
|
integer i;
|
|
|
|
localparam OP_LUI = 7'b0110111,
|
|
OP_AUIPC = 7'b0010111,
|
|
OP_JAL = 7'b1101111,
|
|
OP_JALR = 7'b1100111,
|
|
OP_BRANCH = 7'b1100011,
|
|
OP_LOAD = 7'b0000011,
|
|
OP_STORE = 7'b0100011,
|
|
OP_IMM = 7'b0010011,
|
|
OP_ALU = 7'b0110011,
|
|
OP_FENCE = 7'b0001111,
|
|
OP_SYSTEM = 7'b1110011;
|
|
|
|
localparam INST_NOP = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd0, OP_ALU}; // nop
|
|
|
|
initial begin
|
|
for (i=0; i<MEM_INST_LENGTH; i=i+1) begin
|
|
mem_inst[i] = INST_NOP;
|
|
end
|
|
|
|
// Initialize all registers
|
|
mem_inst[0] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd1, OP_ALU}; // add x1, x0, x0
|
|
mem_inst[1] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd2, OP_ALU}; // add x2, x0, x0
|
|
mem_inst[2] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd3, OP_ALU}; // add x3, x0, x0
|
|
mem_inst[3] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd4, OP_ALU}; // add x4, x0, x0
|
|
mem_inst[4] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd5, OP_ALU}; // add x5, x0, x0
|
|
mem_inst[5] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd6, OP_ALU}; // add x6, x0, x0
|
|
mem_inst[6] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd7, OP_ALU}; // add x7, x0, x0
|
|
mem_inst[7] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd8, OP_ALU}; // add x8, x0, x0
|
|
mem_inst[8] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd9, OP_ALU}; // add x9, x0, x0
|
|
mem_inst[9] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd10, OP_ALU}; // add x10, x0, x0
|
|
mem_inst[10] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd11, OP_ALU}; // add x11, x0, x0
|
|
mem_inst[11] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd12, OP_ALU}; // add x12, x0, x0
|
|
mem_inst[12] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd13, OP_ALU}; // add x13, x0, x0
|
|
mem_inst[13] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd14, OP_ALU}; // add x14, x0, x0
|
|
mem_inst[14] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd15, OP_ALU}; // add x15, x0, x0
|
|
mem_inst[15] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd16, OP_ALU}; // add x16, x0, x0
|
|
mem_inst[16] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd17, OP_ALU}; // add x17, x0, x0
|
|
mem_inst[17] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd18, OP_ALU}; // add x18, x0, x0
|
|
mem_inst[18] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd19, OP_ALU}; // add x19, x0, x0
|
|
mem_inst[19] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd20, OP_ALU}; // add x20, x0, x0
|
|
mem_inst[20] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd21, OP_ALU}; // add x21, x0, x0
|
|
mem_inst[21] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd22, OP_ALU}; // add x22, x0, x0
|
|
mem_inst[22] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd23, OP_ALU}; // add x23, x0, x0
|
|
mem_inst[23] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd24, OP_ALU}; // add x24, x0, x0
|
|
mem_inst[24] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd25, OP_ALU}; // add x25, x0, x0
|
|
mem_inst[25] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd26, OP_ALU}; // add x26, x0, x0
|
|
mem_inst[26] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd27, OP_ALU}; // add x27, x0, x0
|
|
mem_inst[27] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd28, OP_ALU}; // add x28, x0, x0
|
|
mem_inst[28] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd29, OP_ALU}; // add x29, x0, x0
|
|
mem_inst[29] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd30, OP_ALU}; // add x30, x0, x0
|
|
mem_inst[30] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd31, OP_ALU}; // add x31, x0, x0
|
|
|
|
mem_inst[36] = {12'd1, 5'd0, 3'b000, 5'd2, OP_IMM}; // addi x2, x0, 1
|
|
mem_inst[42] = {7'b0000000, 5'd2, 5'd1, 3'b000, 5'd3, OP_ALU}; // add x3, x1, x2
|
|
mem_inst[48] = {7'b0000000, 5'd2, 5'd3, 3'b000, 5'd3, OP_ALU}; // add x3, x3, x2
|
|
mem_inst[54] = {7'b0000000, 5'd3, 5'd3, 3'b000, 5'd3, OP_ALU}; // add x3, x3, x3
|
|
mem_inst[60] = {12'h123, 5'd0, 3'b000, 5'd4, OP_IMM}; // addi x4, x0, 0x123
|
|
mem_inst[66] = {12'h000, 5'd4, 3'b000, 5'd5, OP_IMM}; // addi x5, x4, 0
|
|
mem_inst[72] = {12'hfff, 5'd5, 3'b000, 5'd5, OP_IMM}; // addi x5, x5, -1
|
|
mem_inst[78] = {20'hedcba, 5'd7, OP_LUI}; // lui x7, 0xedcba
|
|
mem_inst[84] = {12'h987, 5'd7, 3'b000, 5'd7, OP_IMM}; // addi x7, x7, 0x987
|
|
mem_inst[90] = {20'h00032, 5'd8, OP_AUIPC}; // auipc x8, 0x32 // 90*4 + 0x32000 = 0x32168
|
|
// mem_inst[96] = {12'd288, 5'd0, 3'b000, 5'd9, OP_JALR}; // jalr x9, x0, 72*4 // unconditional jump to index 72 = 288/4
|
|
mem_inst[102] = {1'b0, 10'd12, 1'b0, 8'b0, 5'd9, OP_JAL}; // jal x10, +12 // unconditional jump to index +12 = 24*2/4
|
|
mem_inst[108] = {12'd4, 5'd0, 3'b000, 5'd2, OP_IMM}; // addi x11, x0, 4 // this should be skipped
|
|
mem_inst[114] = {12'd5, 5'd0, 3'b000, 5'd2, OP_IMM}; // addi x12, x0, 5
|
|
mem_inst[120] = {12'd5, 5'd0, 3'b000, 5'd2, OP_IMM}; // addi x12, x12, 6
|
|
|
|
end
|
|
|
|
always @(*) begin
|
|
if (mem_inst_idx < MEM_INST_LENGTH) begin
|
|
mem_inst_data = mem_inst[mem_inst_idx];
|
|
end else begin
|
|
mem_inst_data = INST_NOP;
|
|
end
|
|
end
|
|
|
|
|
|
|
|
initial begin
|
|
#0
|
|
clk = 0;
|
|
reset = 1;
|
|
|
|
#20
|
|
reset = 0;
|
|
|
|
#5000
|
|
reset = 1;
|
|
$stop;
|
|
end
|
|
|
|
always #10 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_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)
|
|
);
|
|
|
|
endmodule |