Add scripts/presyn/ example
This commit is contained in:
parent
a2107ed4ff
commit
42b4397390
|
@ -0,0 +1,7 @@
|
|||
firmware.bin
|
||||
firmware.elf
|
||||
firmware.hex
|
||||
firmware.map
|
||||
picorv32_presyn.v
|
||||
testbench.vcd
|
||||
testbench.vvp
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
TOOLCHAIN_PREFIX = /opt/riscv32ic/bin/riscv32-unknown-elf-
|
||||
|
||||
run: testbench.vvp firmware.hex
|
||||
vvp -N testbench.vvp
|
||||
|
||||
firmware.hex: firmware.S firmware.c firmware.lds
|
||||
$(TOOLCHAIN_PREFIX)gcc -Os -ffreestanding -nostdlib -o firmware.elf firmware.S firmware.c \
|
||||
--std=gnu99 -Wl,-Bstatic,-T,firmware.lds,-Map,firmware.map,--strip-debug -lgcc
|
||||
$(TOOLCHAIN_PREFIX)objcopy -O binary firmware.elf firmware.bin
|
||||
python3 ../../firmware/makehex.py firmware.bin 4096 > firmware.hex
|
||||
|
||||
picorv32_presyn.v: picorv32_presyn.ys picorv32_regs.txt ../../picorv32.v
|
||||
yosys -v0 picorv32_presyn.ys
|
||||
|
||||
testbench.vvp: testbench.v picorv32_presyn.v
|
||||
iverilog -o testbench.vvp testbench.v picorv32_presyn.v
|
||||
|
||||
clean:
|
||||
rm -f firmware.bin firmware.elf firmware.hex firmware.map
|
||||
rm -f picorv32_presyn.v testbench.vvp testbench.vcd
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
A simple example for how to use Yosys to "pre-synthesize" PicoRV32 in
|
||||
a way that can utilize an external memory module for the register file.
|
||||
|
||||
See also:
|
||||
https://github.com/cliffordwolf/picorv32/issues/30
|
|
@ -0,0 +1,47 @@
|
|||
.section .init
|
||||
.global main
|
||||
|
||||
entry:
|
||||
|
||||
/* zero-initialize all registers */
|
||||
addi x1, zero, 0
|
||||
addi x2, zero, 0
|
||||
addi x3, zero, 0
|
||||
addi x4, zero, 0
|
||||
addi x5, zero, 0
|
||||
addi x6, zero, 0
|
||||
addi x7, zero, 0
|
||||
addi x8, zero, 0
|
||||
addi x9, zero, 0
|
||||
addi x10, zero, 0
|
||||
addi x11, zero, 0
|
||||
addi x12, zero, 0
|
||||
addi x13, zero, 0
|
||||
addi x14, zero, 0
|
||||
addi x15, zero, 0
|
||||
addi x16, zero, 0
|
||||
addi x17, zero, 0
|
||||
addi x18, zero, 0
|
||||
addi x19, zero, 0
|
||||
addi x20, zero, 0
|
||||
addi x21, zero, 0
|
||||
addi x22, zero, 0
|
||||
addi x23, zero, 0
|
||||
addi x24, zero, 0
|
||||
addi x25, zero, 0
|
||||
addi x26, zero, 0
|
||||
addi x27, zero, 0
|
||||
addi x28, zero, 0
|
||||
addi x29, zero, 0
|
||||
addi x30, zero, 0
|
||||
addi x31, zero, 0
|
||||
|
||||
/* set stack pointer */
|
||||
lui sp, %hi(16*1024)
|
||||
addi sp, sp, %lo(16*1024)
|
||||
|
||||
/* call main */
|
||||
jal ra, main
|
||||
|
||||
/* break */
|
||||
ebreak
|
|
@ -0,0 +1,43 @@
|
|||
void putc(char c)
|
||||
{
|
||||
*(volatile char*)0x10000000 = c;
|
||||
}
|
||||
|
||||
void puts(const char *s)
|
||||
{
|
||||
while (*s) putc(*s++);
|
||||
}
|
||||
|
||||
void *memcpy(void *dest, const void *src, int n)
|
||||
{
|
||||
while (n) {
|
||||
n--;
|
||||
((char*)dest)[n] = ((char*)src)[n];
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
char message[] = "$Uryyb+Jbeyq!+Vs+lbh+pna+ernq+guvf+zrffntr+gura$gur+CvpbEI32+PCH"
|
||||
"+frrzf+gb+or+jbexvat+whfg+svar.$$++++++++++++++++GRFG+CNFFRQ!$$";
|
||||
for (int i = 0; message[i]; i++)
|
||||
switch (message[i])
|
||||
{
|
||||
case 'a' ... 'm':
|
||||
case 'A' ... 'M':
|
||||
message[i] += 13;
|
||||
break;
|
||||
case 'n' ... 'z':
|
||||
case 'N' ... 'Z':
|
||||
message[i] -= 13;
|
||||
break;
|
||||
case '$':
|
||||
message[i] = '\n';
|
||||
break;
|
||||
case '+':
|
||||
message[i] = ' ';
|
||||
break;
|
||||
}
|
||||
puts(message);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
SECTIONS {
|
||||
.memory : {
|
||||
. = 0x000000;
|
||||
*(.init);
|
||||
*(.text);
|
||||
*(*);
|
||||
. = ALIGN(4);
|
||||
end = .;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
read_verilog ../../picorv32.v
|
||||
chparam -set COMPRESSED_ISA 1 picorv32
|
||||
prep -top picorv32
|
||||
memory_bram -rules picorv32_regs.txt
|
||||
write_verilog -noattr picorv32_presyn.v
|
|
@ -0,0 +1,16 @@
|
|||
bram picorv32_regs
|
||||
init 0
|
||||
abits 5
|
||||
dbits 32
|
||||
groups 2
|
||||
ports 2 1
|
||||
wrmode 0 1
|
||||
enable 0 1
|
||||
transp 0 0
|
||||
clocks 1 1
|
||||
clkpol 1 1
|
||||
endbram
|
||||
|
||||
match picorv32_regs
|
||||
make_transp
|
||||
endmatch
|
|
@ -0,0 +1,81 @@
|
|||
module testbench;
|
||||
reg clk = 1;
|
||||
always #5 clk = ~clk;
|
||||
|
||||
reg resetn = 0;
|
||||
always @(posedge clk) resetn <= 1;
|
||||
|
||||
wire trap;
|
||||
wire mem_valid;
|
||||
wire mem_instr;
|
||||
reg mem_ready;
|
||||
wire [31:0] mem_addr;
|
||||
wire [31:0] mem_wdata;
|
||||
wire [3:0] mem_wstrb;
|
||||
reg [31:0] mem_rdata;
|
||||
|
||||
picorv32 UUT (
|
||||
.clk (clk ),
|
||||
.resetn (resetn ),
|
||||
.trap (trap ),
|
||||
.mem_valid(mem_valid),
|
||||
.mem_instr(mem_instr),
|
||||
.mem_ready(mem_ready),
|
||||
.mem_addr (mem_addr ),
|
||||
.mem_wdata(mem_wdata),
|
||||
.mem_wstrb(mem_wstrb),
|
||||
.mem_rdata(mem_rdata)
|
||||
);
|
||||
|
||||
// 4096 32bit words = 16kB memory
|
||||
localparam MEM_SIZE = 4096;
|
||||
|
||||
reg [31:0] memory [0:MEM_SIZE-1];
|
||||
initial $readmemh("firmware.hex", memory);
|
||||
|
||||
always @(posedge clk) begin
|
||||
mem_ready <= 0;
|
||||
mem_rdata <= 'bx;
|
||||
|
||||
if (resetn && mem_valid && !mem_ready) begin
|
||||
mem_ready <= 1;
|
||||
if (mem_wstrb) begin
|
||||
if (mem_addr == 32'h1000_0000) begin
|
||||
$write("%c", mem_wdata[7:0]);
|
||||
$fflush;
|
||||
end else begin
|
||||
if (mem_wstrb[0]) memory[mem_addr >> 2][ 7: 0] <= mem_wdata[ 7: 0];
|
||||
if (mem_wstrb[1]) memory[mem_addr >> 2][15: 8] <= mem_wdata[15: 8];
|
||||
if (mem_wstrb[2]) memory[mem_addr >> 2][23:16] <= mem_wdata[23:16];
|
||||
if (mem_wstrb[3]) memory[mem_addr >> 2][31:24] <= mem_wdata[31:24];
|
||||
end
|
||||
end else begin
|
||||
mem_rdata <= memory[mem_addr >> 2];
|
||||
end
|
||||
end
|
||||
|
||||
if (resetn && trap) begin
|
||||
$display("TRAP.");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
$dumpfile("testbench.vcd");
|
||||
$dumpvars(0, testbench);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module picorv32_regs (
|
||||
input [4:0] A1ADDR, A2ADDR, B1ADDR,
|
||||
output reg [31:0] A1DATA, A2DATA,
|
||||
input [31:0] B1DATA,
|
||||
input B1EN, CLK1
|
||||
);
|
||||
reg [31:0] memory [0:31];
|
||||
always @(posedge CLK1) begin
|
||||
A1DATA <= memory[A1ADDR];
|
||||
A2DATA <= memory[A2ADDR];
|
||||
if (B1EN) memory[B1ADDR] <= B1DATA;
|
||||
end
|
||||
endmodule
|
Loading…
Reference in New Issue