suhc goop
This commit is contained in:
parent
3a2c675613
commit
8de052939b
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,4 +2,5 @@ impl/
|
||||||
**/*.gprj*
|
**/*.gprj*
|
||||||
tests/**/*.vcd
|
tests/**/*.vcd
|
||||||
tests/**/out
|
tests/**/out
|
||||||
src/gowin_*/
|
src/gowin_*/
|
||||||
|
**/target/
|
5
Makefile
5
Makefile
|
@ -1,4 +1,7 @@
|
||||||
BOARD = tangnano20k
|
BOARD = tangnano20k
|
||||||
|
|
||||||
flash:
|
flash:
|
||||||
openFPGALoader -m -b ${BOARD} impl/pnr/*.fs
|
openFPGALoader -m -b ${BOARD} impl/pnr/holeybeepo.fs
|
||||||
|
|
||||||
|
debug:
|
||||||
|
openFPGALoader -m -b ${BOARD} impl/pnr/ao_0.fs
|
||||||
|
|
7
slapper/Cargo.lock
generated
Normal file
7
slapper/Cargo.lock
generated
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slapper"
|
||||||
|
version = "0.1.0"
|
8
slapper/Cargo.toml
Normal file
8
slapper/Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "slapper"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
64
slapper/src/main.rs
Normal file
64
slapper/src/main.rs
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
use std::{process::exit, path::PathBuf, fs::File, io::{Read, Write}};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let from = std::env::args().nth(1).unwrap_or_else(|| {
|
||||||
|
println!("You gotta give me a binary file to slap the hex out of");
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
let into = std::env::args().nth(2).unwrap_or_else(|| {
|
||||||
|
println!("I need a file to put these values into");
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
let output = std::env::args().nth(3).unwrap_or_else(|| {
|
||||||
|
println!("I need a file to output to");
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
let from_path: PathBuf = (&from).into();
|
||||||
|
let into_path: PathBuf = (&into).into();
|
||||||
|
let output_path: PathBuf = (&output).into();
|
||||||
|
|
||||||
|
let mut from_file = File::open(&from_path).unwrap_or_else(|e| {
|
||||||
|
println!("Error opening {from_path:?}: {e}");
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut into_file = File::open(&into_path).unwrap_or_else(|e| {
|
||||||
|
println!("Error opening {into_path:?}: {e}");
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut output_file = File::create(&output_path).unwrap_or_else(|e| {
|
||||||
|
println!("Error creating {output_path:?}: {e}");
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut from_contents: Vec<u8> = Vec::with_capacity(128);
|
||||||
|
let mut into_contents: String = String::with_capacity(1024);
|
||||||
|
|
||||||
|
from_file.read_to_end(&mut from_contents).unwrap_or_else(|e| {
|
||||||
|
println!("Failed to read {from_path:?} {e}");
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
into_file.read_to_string(&mut into_contents).unwrap_or_else(|e| {
|
||||||
|
println!("Failed to read {into_path:?}: {e}");
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
let mem_value: String = from_contents.iter().map(|byte| {
|
||||||
|
format!("{byte:02X}")
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
let bit_length = from_contents.len() * 8;
|
||||||
|
let insert_mem = format!("reg [0:{}] mem = {bit_length}'h{mem_value};", bit_length - 1);
|
||||||
|
|
||||||
|
into_contents = into_contents.replace("$$insert_mem$$", &insert_mem);
|
||||||
|
|
||||||
|
output_file.write_all(into_contents.as_bytes()).unwrap_or_else(|e| {
|
||||||
|
println!("Failed writing to {output_path:?}: {e}");
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ module Beepo #(
|
||||||
input i_button1,
|
input i_button1,
|
||||||
output [6:0] o_segments_drive,
|
output [6:0] o_segments_drive,
|
||||||
output [3:0] o_displays_neg
|
output [3:0] o_displays_neg
|
||||||
);
|
);
|
||||||
// State values
|
// State values
|
||||||
localparam IDLE = 0; // Start fetching instruction
|
localparam IDLE = 0; // Start fetching instruction
|
||||||
localparam FETCHI = 1; // Instruction is fetched, start fetching first argument
|
localparam FETCHI = 1; // Instruction is fetched, start fetching first argument
|
||||||
|
@ -29,7 +29,7 @@ module Beepo #(
|
||||||
|
|
||||||
localparam [0:31] ARG_SIZES = {4'd1, 4'd4, 4'd2, 4'd1, 4'd2, 4'd4, 4'd8, 4'd8};
|
localparam [0:31] ARG_SIZES = {4'd1, 4'd4, 4'd2, 4'd1, 4'd2, 4'd4, 4'd8, 4'd8};
|
||||||
|
|
||||||
localparam PC_START = 1;
|
localparam PC_START = 0;
|
||||||
localparam NUM_REGS = 4;
|
localparam NUM_REGS = 4;
|
||||||
|
|
||||||
reg [2:0] r_state = IDLE;
|
reg [2:0] r_state = IDLE;
|
||||||
|
@ -185,6 +185,8 @@ module Beepo #(
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
task automatic set_register(
|
task automatic set_register(
|
||||||
input [7:0] being_set,
|
input [7:0] being_set,
|
||||||
input [63:0] setting_to
|
input [63:0] setting_to
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
//Device Version: C
|
//Device Version: C
|
||||||
//Created Time: Tue 11 14 12:00:04 2023
|
//Created Time: Tue 11 14 12:00:04 2023
|
||||||
|
|
||||||
IO_LOC "o_uart_tx" 69;
|
//IO_LOC "o_uart_tx" 69;
|
||||||
IO_PORT "o_uart_tx" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
|
//IO_PORT "o_uart_tx" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
|
||||||
IO_LOC "i_clk" 4;
|
IO_LOC "i_clk" 4;
|
||||||
IO_PORT "i_clk" PULL_MODE=UP BANK_VCCIO=1.8;
|
IO_PORT "i_clk" PULL_MODE=UP BANK_VCCIO=1.8;
|
||||||
IO_LOC "o_displays_neg[3]" 80;
|
IO_LOC "o_displays_neg[3]" 80;
|
||||||
|
|
30
tests/Makefile
Normal file
30
tests/Makefile
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
ICARUS_FILES = inputs.txt
|
||||||
|
|
||||||
|
# Used in all tests
|
||||||
|
build:
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
|
release/slapper:
|
||||||
|
cargo build --manifest-path ../slapper/Cargo.toml -r
|
||||||
|
|
||||||
|
slapper: release/slapper
|
||||||
|
cp ../slapper/target/release/slapper $@
|
||||||
|
|
||||||
|
# Addition tests
|
||||||
|
build/adding: | build
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
|
build/adding/program.bin: adding/program.rhai | build/adding
|
||||||
|
./hbasm $< > $@
|
||||||
|
|
||||||
|
build/adding/spmem_gen.v: build/adding/program.bin slapper | build/adding
|
||||||
|
./slapper $< spmem.v $@
|
||||||
|
|
||||||
|
build/adding/out: ${ICARUS_FILES} build/adding/spmem_gen.v | build/adding
|
||||||
|
iverilog -o $@ -c $< -s tb_adding
|
||||||
|
|
||||||
|
build/adding/dump.vcd: build/adding/out | build/adding
|
||||||
|
vvp $<
|
||||||
|
|
||||||
|
adding-wave: build/adding/dump.vcd | build/adding
|
||||||
|
gtkwave build/adding/dump.vcd
|
|
@ -1,11 +0,0 @@
|
||||||
ICARUS_FILES = inputs.txt
|
|
||||||
ICARUS_OUT = out
|
|
||||||
|
|
||||||
build: ${ICARUS_FILES}
|
|
||||||
iverilog -o ${ICARUS_OUT} -c $^ -s tb_adding
|
|
||||||
|
|
||||||
run: build
|
|
||||||
vvp ${ICARUS_OUT}
|
|
||||||
|
|
||||||
wave: run
|
|
||||||
gtkwave dump.vcd
|
|
1
tests/adding/adding.bin
Normal file
1
tests/adding/adding.bin
Normal file
|
@ -0,0 +1 @@
|
||||||
|
HIJK-./0
|
1
tests/adding/build/adding.bin
Normal file
1
tests/adding/build/adding.bin
Normal file
|
@ -0,0 +1 @@
|
||||||
|
HIJK-./0
|
24
tests/adding/build/spmem_gen.v
Normal file
24
tests/adding/build/spmem_gen.v
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
module spMem(
|
||||||
|
output [7:0] dout,
|
||||||
|
input clk,
|
||||||
|
input oce,
|
||||||
|
input ce,
|
||||||
|
input reset,
|
||||||
|
input wre,
|
||||||
|
input [15:0] ad,
|
||||||
|
input [7:0] din
|
||||||
|
);
|
||||||
|
// gets replaced with the memory for the program to run
|
||||||
|
reg [0:535] mem = 536'h480110490210104A03101010104B041010101010101010030101010401010205010103060101042D0101102E010110102F010110101010300101101010101010101001;
|
||||||
|
|
||||||
|
reg [15:0] r_ad_prev = 0;
|
||||||
|
reg [7:0] r_out;
|
||||||
|
|
||||||
|
assign dout = r_out;
|
||||||
|
|
||||||
|
always @(negedge clk) begin
|
||||||
|
// one full clock cycle before being fetched
|
||||||
|
if (r_ad_prev == ad) r_out <= mem[ad*8+:8];
|
||||||
|
else r_ad_prev = ad;
|
||||||
|
end
|
||||||
|
endmodule
|
7
tests/adding/mem.py
Normal file
7
tests/adding/mem.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
with open("adding.bin", "rb") as f:
|
||||||
|
content = f.read()
|
||||||
|
length_bits = len(content) * 8
|
||||||
|
mash = "".join([hex(int(i))[2:].zfill(2) for i in content])
|
||||||
|
shadow = f"reg [0:{length_bits-1}] mem = {length_bits}'h{mash}; // generated"
|
||||||
|
|
||||||
|
print(shadow)
|
16
tests/adding/program.rhai
Normal file
16
tests/adding/program.rhai
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
li8 (r1, 0x10);
|
||||||
|
li16 (r2, 0x1010);
|
||||||
|
li32 (r3, 0x10101010);
|
||||||
|
li64 (r4, 0x1010101010101010);
|
||||||
|
|
||||||
|
add8 (r1, r1, r1);
|
||||||
|
add16 (r1, r1, r2);
|
||||||
|
add32 (r1, r1, r3);
|
||||||
|
add64 (r1, r1, r4);
|
||||||
|
|
||||||
|
addi8 (r1, r1, 0x10);
|
||||||
|
addi16 (r1, r1, 0x1010);
|
||||||
|
addi32 (r1, r1, 0x10101010);
|
||||||
|
addi64 (r1, r1, 0x1010101010101010);
|
||||||
|
|
||||||
|
tx();
|
|
@ -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
|
|
0
tests/build/adding.bin
Normal file
0
tests/build/adding.bin
Normal file
0
tests/build/adding/program.bin
Normal file
0
tests/build/adding/program.bin
Normal file
24
tests/build/adding/spmem_gen.v
Normal file
24
tests/build/adding/spmem_gen.v
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
module spMem(
|
||||||
|
output [7:0] dout,
|
||||||
|
input clk,
|
||||||
|
input oce,
|
||||||
|
input ce,
|
||||||
|
input reset,
|
||||||
|
input wre,
|
||||||
|
input [15:0] ad,
|
||||||
|
input [7:0] din
|
||||||
|
);
|
||||||
|
// gets replaced with the memory for the program to run
|
||||||
|
reg [0:18446744073709551615] mem = 0'h;
|
||||||
|
|
||||||
|
reg [15:0] r_ad_prev = 0;
|
||||||
|
reg [7:0] r_out;
|
||||||
|
|
||||||
|
assign dout = r_out;
|
||||||
|
|
||||||
|
always @(negedge clk) begin
|
||||||
|
// one full clock cycle before being fetched
|
||||||
|
if (r_ad_prev == ad) r_out <= mem[ad*8+:8];
|
||||||
|
else r_ad_prev = ad;
|
||||||
|
end
|
||||||
|
endmodule
|
24
tests/build/adding_mem.v
Normal file
24
tests/build/adding_mem.v
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
module spMem(
|
||||||
|
output [7:0] dout,
|
||||||
|
input clk,
|
||||||
|
input oce,
|
||||||
|
input ce,
|
||||||
|
input reset,
|
||||||
|
input wre,
|
||||||
|
input [15:0] ad,
|
||||||
|
input [7:0] din
|
||||||
|
);
|
||||||
|
// gets replaced with the memory for the program to run
|
||||||
|
reg [0:18446744073709551615] mem = 0'h;
|
||||||
|
|
||||||
|
reg [15:0] r_ad_prev = 0;
|
||||||
|
reg [7:0] r_out;
|
||||||
|
|
||||||
|
assign dout = r_out;
|
||||||
|
|
||||||
|
always @(negedge clk) begin
|
||||||
|
// one full clock cycle before being fetched
|
||||||
|
if (r_ad_prev == ad) r_out <= mem[ad*8+:8];
|
||||||
|
else r_ad_prev = ad;
|
||||||
|
end
|
||||||
|
endmodule
|
BIN
tests/hbasm
Executable file
BIN
tests/hbasm
Executable file
Binary file not shown.
|
@ -2,4 +2,4 @@
|
||||||
adding.v
|
adding.v
|
||||||
../../src/uart_tx.v
|
../../src/uart_tx.v
|
||||||
../../src/multi7.v
|
../../src/multi7.v
|
||||||
spmem.v
|
../build/adding_mem.v
|
BIN
tests/slapper
Executable file
BIN
tests/slapper
Executable file
Binary file not shown.
24
tests/spmem.v
Normal file
24
tests/spmem.v
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
module spMem(
|
||||||
|
output [7:0] dout,
|
||||||
|
input clk,
|
||||||
|
input oce,
|
||||||
|
input ce,
|
||||||
|
input reset,
|
||||||
|
input wre,
|
||||||
|
input [15:0] ad,
|
||||||
|
input [7:0] din
|
||||||
|
);
|
||||||
|
// gets replaced with the memory for the program to run
|
||||||
|
$$insert_mem$$
|
||||||
|
|
||||||
|
reg [15:0] r_ad_prev = 0;
|
||||||
|
reg [7:0] r_out;
|
||||||
|
|
||||||
|
assign dout = r_out;
|
||||||
|
|
||||||
|
always @(negedge clk) begin
|
||||||
|
// one full clock cycle before being fetched
|
||||||
|
if (r_ad_prev == ad) r_out <= mem[ad*8+:8];
|
||||||
|
else r_ad_prev = ad;
|
||||||
|
end
|
||||||
|
endmodule
|
Loading…
Reference in a new issue