Compare commits

..

No commits in common. "53d08b6c04827e58afe681f6e8062386801b806f" and "6abbabb7eca0351c20e088dbd962ab0c991bc4f6" have entirely different histories.

12 changed files with 111 additions and 174 deletions

6
.gitignore vendored
View file

@ -1,5 +1,5 @@
impl/ impl/
**/*.gprj* **/*.gprj
tests/**/*.vcd tests/*.vcd
tests/**/out tests/out
src/gowin_*/ src/gowin_*/

24
holeybeepo.gprj.user Normal file
View file

@ -0,0 +1,24 @@
<?xml version="1" encoding="UTF-8"?>
<!DOCTYPE ProjectUserData>
<UserConfig>
<Version>1.0</Version>
<FlowState>
<Process ID="Synthesis" State="2"/>
<Process ID="Pnr" State="2"/>
<Process ID="Gao" State="2"/>
<Process ID="Rtl_Gao" State="2"/>
</FlowState>
<ResultFileList>
<ResultFile ResultFileType="RES.netlist" ResultFilePath="impl/gwsynthesis/holeybeepo.vg"/>
<ResultFile ResultFileType="RES.pnr.bitstream" ResultFilePath="impl/pnr/holeybeepo.fs"/>
<ResultFile ResultFileType="RES.pnr.pin.rpt" ResultFilePath="impl/pnr/holeybeepo.pin.html"/>
<ResultFile ResultFileType="RES.pnr.posp.bin" ResultFilePath="impl/pnr/holeybeepo.db"/>
<ResultFile ResultFileType="RES.pnr.pwr.rpt" ResultFilePath="impl/pnr/holeybeepo.power.html"/>
<ResultFile ResultFileType="RES.pnr.report" ResultFilePath="impl/pnr/holeybeepo.rpt.html"/>
<ResultFile ResultFileType="RES.pnr.timing.paths" ResultFilePath="impl/pnr/holeybeepo.timing_paths"/>
<ResultFile ResultFileType="RES.pnr.timing.rpt" ResultFilePath="impl/pnr/holeybeepo.tr.html"/>
<ResultFile ResultFileType="RES.syn.report" ResultFilePath="impl/gwsynthesis/holeybeepo_syn.rpt.html"/>
<ResultFile ResultFileType="RES.syn.resource" ResultFilePath="impl/gwsynthesis/holeybeepo_syn_rsc.xml"/>
</ResultFileList>
<Ui>000000ff00000001fd00000002000000000000010000000260fc0200000001fc00000038000002600000008a01000018fa000000000200000004fb00000030004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00440065007300690067006e0100000000ffffffff0000005600fffffffb00000036004600700067006100500072006f006a006500630074002e00500061006e0065006c002e0048006900650072006100720063006800790100000000ffffffff0000007100fffffffb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00500072006f00630065007300730100000000ffffffff0000005200fffffffb00000030004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00440065007300690067006e0100000000ffffffff00000000000000000000000300000776000000f2fc0100000001fc0000000000000776000000a500fffffffa000000000100000003fb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00470065006e006500720061006c0100000000ffffffff0000004700fffffffb0000002e004600700067006100500072006f006a006500630074002e00500061006e0065006c002e004900730073007500650100000000ffffffff000000a500fffffffb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00470065006e006500720061006c0100000000ffffffff0000000000000000000006700000026000000004000000040000000800000008fc000000010000000200000004000000220043006f00720065002e0054006f006f006c006200610072002e00460069006c00650100000000ffffffff0000000000000000000000220043006f00720065002e0054006f006f006c006200610072002e0045006400690074010000009bffffffff0000000000000000000000240043006f00720065002e0054006f006f006c006200610072002e0054006f006f006c00730100000157ffffffff0000000000000000ffffffff0100000207ffffffff0000000000000000</Ui>
</UserConfig>

View file

@ -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; // Double-word, 64 bit localparam [3:0] ARG_D = 6; // D{gtkwave NET OFF} ouble-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]; // up to 255 modifiable registers reg [63:0] r_registers [0:NUM_REGS-1]; // the 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; i = i + 1) begin for (i = 1; i < NUM_REGS-1; i = i + 1) begin
initial r_registers[i] <= 0; initial r_registers[i] <= 0;
end end
endgenerate endgenerate
@ -86,21 +86,12 @@ 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; `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; default: r_arg_types_packed = {ARG_N, ARG_N, ARG_N, ARG_N};
`ADDI8: r_arg_types_packed = `ADDI8_ARGS;
`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
@ -173,20 +164,11 @@ 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]); `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]);
`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];
@ -219,7 +201,7 @@ module Beepo #(
Multi7 display ( Multi7 display (
.i_clk(i_clk), .i_clk(i_clk),
.i_hex({r_registers[1][15:0]}), .i_hex({r_registers[1][7:0], r_registers[2][7:0]}),
.o_segments_drive(o_segments_drive), .o_segments_drive(o_segments_drive),
.o_displays_neg(o_displays_neg) .o_displays_neg(o_displays_neg)
); );

View file

@ -11,12 +11,6 @@
// Binary register-register operations // Binary register-register operations
`define ADD8 'h03 `define ADD8 'h03
`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_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
@ -28,12 +22,6 @@
// 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
@ -44,12 +32,6 @@
// Load immediate // Load immediate
`define LI8 'h48 `define LI8 'h48
`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_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

View file

@ -1,35 +0,0 @@
#File_format=Bin
#Address_depth=32
#Data_width=8
00000000
01001001
00000001
00100011
01000110
01001001
00000010
01000110
00100011
00000011
00000001
00000001
00000010
00000001
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000

View file

@ -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_adding iverilog -o ${ICARUS_OUT} -c $^ -s tb_beepo -g2005-sv
run: build vvp: build
vvp ${ICARUS_OUT} vvp ${ICARUS_OUT}
wave: vvp wave: vvp

View file

@ -1,42 +0,0 @@
`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

View file

@ -1,5 +0,0 @@
../../src/instructions.v
adding.v
../../src/uart_tx.v
../../src/multi7.v
spmem.v

View file

@ -1,35 +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: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

34
tests/beepo.v Normal file
View file

@ -0,0 +1,34 @@
`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

5
tests/inputs.txt Normal file
View file

@ -0,0 +1,5 @@
../src/instructions.v
beepo.v
../src/uart_tx.v
../src/multi7.v
spmem.v

27
tests/spmem.v Normal file
View file

@ -0,0 +1,27 @@
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'h48, 8'h01, 8'h23,
8'h48, 8'h02, 8'h46,
8'h03, 8'h01, 8'h01, 8'h02,
8'h01,
160'h0
};
reg [7:0] r_out;
assign dout = r_out;
always @(negedge clk) begin
r_out <= mem[ad*8+:8];
end
endmodule