the rest of LI, ADD and ADDI
This commit is contained in:
parent
00eadf1b64
commit
53d08b6c04
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,5 +1,5 @@
|
||||||
impl/
|
impl/
|
||||||
**/*.gprj*
|
**/*.gprj*
|
||||||
tests/*.vcd
|
tests/**/*.vcd
|
||||||
tests/out
|
tests/**/out
|
||||||
src/gowin_*/
|
src/gowin_*/
|
52
src/beepo.v
52
src/beepo.v
|
@ -1,4 +1,4 @@
|
||||||
`include "instructions.v"
|
// `include "instructions.v"
|
||||||
|
|
||||||
module Beepo #(
|
module Beepo #(
|
||||||
parameter FREQ = 27_000_000,
|
parameter FREQ = 27_000_000,
|
||||||
|
@ -24,7 +24,7 @@ module Beepo #(
|
||||||
localparam [3:0] ARG_B = 3; // Byte, 8 bit
|
localparam [3:0] ARG_B = 3; // Byte, 8 bit
|
||||||
localparam [3:0] ARG_H = 4; // Half-word, 16 bit
|
localparam [3:0] ARG_H = 4; // Half-word, 16 bit
|
||||||
localparam [3:0] ARG_W = 5; // Word, 32 bit
|
localparam [3:0] ARG_W = 5; // Word, 32 bit
|
||||||
localparam [3:0] ARG_D = 6; // D{gtkwave NET OFF} ouble-word, 64 bit
|
localparam [3:0] ARG_D = 6; // Double-word, 64 bit
|
||||||
localparam [3:0] ARG_A = 7; // Absolute address immediate, 64 bit
|
localparam [3:0] ARG_A = 7; // Absolute address immediate, 64 bit
|
||||||
localparam [3:0] ARG_N = 8; // No argument
|
localparam [3:0] ARG_N = 8; // No argument
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ module Beepo #(
|
||||||
// Registers
|
// Registers
|
||||||
reg [63:0] r_pc = PC_START; // program counter
|
reg [63:0] r_pc = PC_START; // program counter
|
||||||
reg [63:0] r_pc_latch = PC_START; // address input to ROM
|
reg [63:0] r_pc_latch = PC_START; // address input to ROM
|
||||||
reg [63:0] r_registers [0:NUM_REGS-1]; // the 255 modifiable registers
|
reg [63:0] r_registers [0:NUM_REGS]; // up to 255 modifiable registers
|
||||||
reg [7:0] r_instr; // the current instruction
|
reg [7:0] r_instr; // the current instruction
|
||||||
reg [7:0] r_arg_regs [0:3]; // register arguments
|
reg [7:0] r_arg_regs [0:3]; // register arguments
|
||||||
reg [63:0] r_arg_imm = 0; // immediate argument
|
reg [63:0] r_arg_imm = 0; // immediate argument
|
||||||
|
@ -63,7 +63,7 @@ module Beepo #(
|
||||||
genvar i;
|
genvar i;
|
||||||
|
|
||||||
generate
|
generate
|
||||||
for (i = 1; i < NUM_REGS-1; i = i + 1) begin
|
for (i = 1; i <= NUM_REGS; i = i + 1) begin
|
||||||
initial r_registers[i] <= 0;
|
initial r_registers[i] <= 0;
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
@ -86,14 +86,21 @@ module Beepo #(
|
||||||
r_arg_bit <= 0;
|
r_arg_bit <= 0;
|
||||||
|
|
||||||
case (w_mem_fetch)
|
case (w_mem_fetch)
|
||||||
`TX: r_arg_types_packed = `TX_ARGS;
|
`TX: r_arg_types_packed = `TX_ARGS;
|
||||||
`NOP: r_arg_types_packed = `NOP_ARGS;
|
`NOP: r_arg_types_packed = `NOP_ARGS;
|
||||||
`ADD8: r_arg_types_packed = `ADD8_ARGS;
|
`ADD8: r_arg_types_packed = `ADD8_ARGS;
|
||||||
`ADD16: r_arg_types_packed = `ADD16_ARGS;
|
`ADD16: r_arg_types_packed = `ADD16_ARGS;
|
||||||
`ADDI8: r_arg_types_packed = `ADDI8_ARGS;
|
`ADD32: r_arg_types_packed = `ADD32_ARGS;
|
||||||
`LI8: r_arg_types_packed = `LI8_ARGS;
|
`ADD64: r_arg_types_packed = `ADD64_ARGS;
|
||||||
`LI16: r_arg_types_packed = `LI16_ARGS;
|
`ADDI8: r_arg_types_packed = `ADDI8_ARGS;
|
||||||
default: r_arg_types_packed = {ARG_N, ARG_N, ARG_N, ARG_N};
|
`ADDI16: r_arg_types_packed = `ADDI16_ARGS;
|
||||||
|
`ADDI32: r_arg_types_packed = `ADDI32_ARGS;
|
||||||
|
`ADDI64: r_arg_types_packed = `ADDI64_ARGS;
|
||||||
|
`LI8: r_arg_types_packed = `LI8_ARGS;
|
||||||
|
`LI16: r_arg_types_packed = `LI16_ARGS;
|
||||||
|
`LI32: r_arg_types_packed = `LI32_ARGS;
|
||||||
|
`LI64: r_arg_types_packed = `LI64_ARGS;
|
||||||
|
default: r_arg_types_packed = {ARG_N, ARG_N, ARG_N, ARG_N};
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
if (r_arg_types_packed[15:12] != ARG_N) begin
|
if (r_arg_types_packed[15:12] != ARG_N) begin
|
||||||
|
@ -166,13 +173,20 @@ module Beepo #(
|
||||||
r_state <= FETCHI;
|
r_state <= FETCHI;
|
||||||
|
|
||||||
case (r_instr)
|
case (r_instr)
|
||||||
`TX: r_state <= DONE;
|
`TX: r_state <= DONE;
|
||||||
`NOP: ;
|
`NOP: ;
|
||||||
`ADD8: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][7:0]);
|
`ADD8: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][7:0]);
|
||||||
`ADD16: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][15:0]);
|
`ADD16: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][15:0]);
|
||||||
`ADDI8: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[7:0]);
|
`ADD32: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][31:0]);
|
||||||
`LI8: set_register(r_arg_regs[0], r_arg_imm);
|
`ADD64: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_registers[r_arg_regs[2]][63:0]);
|
||||||
`LI16: set_register(r_arg_regs[0], r_arg_imm);
|
`ADDI8: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[7:0]);
|
||||||
|
`ADDI16: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[15:0]);
|
||||||
|
`ADDI32: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[31:0]);
|
||||||
|
`ADDI64: set_register(r_arg_regs[0], r_registers[r_arg_regs[1]] + r_arg_imm[63:0]);
|
||||||
|
`LI8: set_register(r_arg_regs[0], r_arg_imm);
|
||||||
|
`LI16: set_register(r_arg_regs[0], r_arg_imm);
|
||||||
|
`LI32: set_register(r_arg_regs[0], r_arg_imm);
|
||||||
|
`LI64: set_register(r_arg_regs[0], r_arg_imm);
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
// r_tx_send_ctrl[0] <= ~r_tx_send_ctrl[0];
|
// r_tx_send_ctrl[0] <= ~r_tx_send_ctrl[0];
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
`define ADD8_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
|
`define ADD8_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
|
||||||
`define ADD16 'h04
|
`define ADD16 'h04
|
||||||
`define ADD16_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
|
`define ADD16_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
|
||||||
|
`define ADD32 'h05
|
||||||
|
`define ADD32_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
|
||||||
|
`define ADD64 'h06
|
||||||
|
`define ADD64_ARGS {ARG_R, ARG_R, ARG_R, ARG_N}
|
||||||
|
|
||||||
// Merged divide-remainder
|
// Merged divide-remainder
|
||||||
`define DIRU8 'h20
|
`define DIRU8 'h20
|
||||||
|
@ -24,6 +28,12 @@
|
||||||
// Binary register-immediate operations
|
// Binary register-immediate operations
|
||||||
`define ADDI8 'h2D
|
`define ADDI8 'h2D
|
||||||
`define ADDI8_ARGS {ARG_R, ARG_R, ARG_B, ARG_N}
|
`define ADDI8_ARGS {ARG_R, ARG_R, ARG_B, ARG_N}
|
||||||
|
`define ADDI16 'h2E
|
||||||
|
`define ADDI16_ARGS {ARG_R, ARG_R, ARG_H, ARG_N}
|
||||||
|
`define ADDI32 'h2F
|
||||||
|
`define ADDI32_ARGS {ARG_R, ARG_R, ARG_W, ARG_N}
|
||||||
|
`define ADDI64 'h30
|
||||||
|
`define ADDI64_ARGS {ARG_R, ARG_R, ARG_D, ARG_N}
|
||||||
|
|
||||||
// Register-immediate bitshifts
|
// Register-immediate bitshifts
|
||||||
`define SLUI8 'h38
|
`define SLUI8 'h38
|
||||||
|
@ -36,6 +46,10 @@
|
||||||
`define LI8_ARGS {ARG_R, ARG_B, ARG_N, ARG_N}
|
`define LI8_ARGS {ARG_R, ARG_B, ARG_N, ARG_N}
|
||||||
`define LI16 'h49
|
`define LI16 'h49
|
||||||
`define LI16_ARGS {ARG_R, ARG_H, ARG_N, ARG_N}
|
`define LI16_ARGS {ARG_R, ARG_H, ARG_N, ARG_N}
|
||||||
|
`define LI32 'h4A
|
||||||
|
`define LI32_ARGS {ARG_R, ARG_W, ARG_N, ARG_N}
|
||||||
|
`define LI64 'h4B
|
||||||
|
`define LI64_ARGS {ARG_R, ARG_D, ARG_N, ARG_N}
|
||||||
|
|
||||||
// Conditional jump
|
// Conditional jump
|
||||||
`define JEQ 'h56
|
`define JEQ 'h56
|
|
@ -2,9 +2,9 @@ ICARUS_FILES = inputs.txt
|
||||||
ICARUS_OUT = out
|
ICARUS_OUT = out
|
||||||
|
|
||||||
build: ${ICARUS_FILES}
|
build: ${ICARUS_FILES}
|
||||||
iverilog -o ${ICARUS_OUT} -c $^ -s tb_beepo -g2005-sv
|
iverilog -o ${ICARUS_OUT} -c $^ -s tb_adding
|
||||||
|
|
||||||
vvp: build
|
run: build
|
||||||
vvp ${ICARUS_OUT}
|
vvp ${ICARUS_OUT}
|
||||||
|
|
||||||
wave: vvp
|
wave: vvp
|
42
tests/adding/adding.v
Normal file
42
tests/adding/adding.v
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
`include "../../src/beepo.v"
|
||||||
|
`timescale 100us/10ns
|
||||||
|
|
||||||
|
`define assert(signal, value) \
|
||||||
|
if (signal !== value) begin \
|
||||||
|
$display("ASSERTION FAILED in %m: signal != value"); \
|
||||||
|
$finish; \
|
||||||
|
end
|
||||||
|
|
||||||
|
module tb_adding(
|
||||||
|
output o_uart_tx
|
||||||
|
);
|
||||||
|
|
||||||
|
reg clk = 0;
|
||||||
|
|
||||||
|
Beepo #(
|
||||||
|
.FREQ(1),
|
||||||
|
.UART_BAUD(1_000_000)
|
||||||
|
) bep (
|
||||||
|
.i_clk(clk),
|
||||||
|
.o_uart_tx(o_uart_tx)
|
||||||
|
);
|
||||||
|
localparam CLK_PERIOD = 1.0;
|
||||||
|
always #(CLK_PERIOD/2) clk=~clk;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$dumpfile("dump.vcd");
|
||||||
|
$dumpvars(0, tb_adding,
|
||||||
|
bep.r_registers[1], bep.r_registers[2],
|
||||||
|
bep.r_arg_types[0], bep.r_arg_types[1],
|
||||||
|
bep.r_arg_types[2], bep.r_arg_types[3],
|
||||||
|
bep.r_arg_regs[0], bep.r_arg_regs[1],
|
||||||
|
bep.r_arg_regs[2], bep.r_arg_regs[3]
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
// should probably do more tests than just the end
|
||||||
|
initial #10000 begin
|
||||||
|
`assert(bep.r_registers[1], 64'h2020202040406090);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
5
tests/adding/inputs.txt
Normal file
5
tests/adding/inputs.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
../../src/instructions.v
|
||||||
|
adding.v
|
||||||
|
../../src/uart_tx.v
|
||||||
|
../../src/multi7.v
|
||||||
|
spmem.v
|
35
tests/adding/spmem.v
Normal file
35
tests/adding/spmem.v
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
module spMem(
|
||||||
|
output [7:0] dout,
|
||||||
|
input clk,
|
||||||
|
input oce,
|
||||||
|
input ce,
|
||||||
|
input reset,
|
||||||
|
input wre,
|
||||||
|
input [15:0] ad,
|
||||||
|
input [7:0] din
|
||||||
|
);
|
||||||
|
reg [0:543] mem = {
|
||||||
|
8'h0,
|
||||||
|
8'h48, 8'h01, 8'h10, // r1 <- 0x10
|
||||||
|
8'h49, 8'h02, 16'h1010, // r2 <- 0x1010
|
||||||
|
8'h4A, 8'h03, 32'h10101010, // r3 <- 0x10101010
|
||||||
|
8'h4B, 8'h04, 64'h1010101010101010, // r4 <- 0x1010101010101010
|
||||||
|
8'h03, 8'h01, 8'h01, 8'h01, // r1 <- r1 + r1 (r1 = 0x20)
|
||||||
|
8'h04, 8'h01, 8'h01, 8'h02, // r1 <- r1 + r2 (r1 = 0x1030)
|
||||||
|
8'h05, 8'h01, 8'h01, 8'h03, // r1 <- r1 + r3 (r1 = 0x10102040)
|
||||||
|
8'h06, 8'h01, 8'h01, 8'h04, // r1 <- r1 + r4 (r1 = 0x1010101020203050)
|
||||||
|
8'h2D, 8'h01, 8'h01, 8'h10, // r1 <- r1 + 0x10 (r1 = 0x1010101020203060)
|
||||||
|
8'h2E, 8'h01, 8'h01, 16'h1010, // r1 <- r1 + 0x1010 (r1 = 0x1010101020204070)
|
||||||
|
8'h2F, 8'h01, 8'h01, 32'h10101010, // r1 <- r1 + 0x10101010 (r1 = 0x1010101030305080)
|
||||||
|
8'h30, 8'h01, 8'h01, 64'h1010101010101010, // r1 <- r1 + 0x1010101010101010 (r1 = 0x2020202040406090)
|
||||||
|
8'h01 // die
|
||||||
|
};
|
||||||
|
|
||||||
|
reg [7:0] r_out;
|
||||||
|
|
||||||
|
assign dout = r_out;
|
||||||
|
|
||||||
|
always @(negedge clk) begin
|
||||||
|
r_out <= mem[ad*8+:8];
|
||||||
|
end
|
||||||
|
endmodule
|
|
@ -1,34 +0,0 @@
|
||||||
`include "../src/beepo.v"
|
|
||||||
`timescale 100us/10ns
|
|
||||||
|
|
||||||
module tb_beepo(
|
|
||||||
output o_uart_tx
|
|
||||||
);
|
|
||||||
|
|
||||||
reg clk = 0;
|
|
||||||
|
|
||||||
Beepo #(
|
|
||||||
.FREQ(1),
|
|
||||||
.UART_BAUD(1_000_000)
|
|
||||||
) bep (
|
|
||||||
.i_clk(clk),
|
|
||||||
.o_uart_tx(o_uart_tx)
|
|
||||||
);
|
|
||||||
|
|
||||||
localparam CLK_PERIOD = 1.0;
|
|
||||||
always #(CLK_PERIOD/2) clk=~clk;
|
|
||||||
|
|
||||||
initial begin
|
|
||||||
$dumpfile("dump.vcd");
|
|
||||||
$dumpvars(0, tb_beepo,
|
|
||||||
bep.r_registers[1], bep.r_registers[2],
|
|
||||||
bep.r_arg_types[0], bep.r_arg_types[1],
|
|
||||||
bep.r_arg_types[2], bep.r_arg_types[3],
|
|
||||||
bep.r_arg_regs[0], bep.r_arg_regs[1],
|
|
||||||
bep.r_arg_regs[2], bep.r_arg_regs[3]
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
initial #10000 $finish;
|
|
||||||
|
|
||||||
endmodule
|
|
|
@ -1,5 +0,0 @@
|
||||||
../src/instructions.v
|
|
||||||
beepo.v
|
|
||||||
../src/uart_tx.v
|
|
||||||
../src/multi7.v
|
|
||||||
spmem.v
|
|
|
@ -1,27 +0,0 @@
|
||||||
module spMem(
|
|
||||||
output [7:0] dout,
|
|
||||||
input clk,
|
|
||||||
input oce,
|
|
||||||
input ce,
|
|
||||||
input reset,
|
|
||||||
input wre,
|
|
||||||
input [15:0] ad,
|
|
||||||
input [7:0] din
|
|
||||||
);
|
|
||||||
reg [0:255] mem = {
|
|
||||||
8'h0,
|
|
||||||
8'h49, 8'h01, 8'h23, 8'h46,
|
|
||||||
8'h49, 8'h02, 8'h46, 8'h23,
|
|
||||||
8'h03, 8'h01, 8'h01, 8'h02,
|
|
||||||
8'h01,
|
|
||||||
144'h0
|
|
||||||
};
|
|
||||||
|
|
||||||
reg [7:0] r_out;
|
|
||||||
|
|
||||||
assign dout = r_out;
|
|
||||||
|
|
||||||
always @(negedge clk) begin
|
|
||||||
r_out <= mem[ad*8+:8];
|
|
||||||
end
|
|
||||||
endmodule
|
|
Loading…
Reference in a new issue