Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ verify/sby/
test/__pycache__/
test/*.vcd
test/*results.xml
test/*results-32.xml
test/*results-64.xml
stats.md
test/sim_build/

10 changes: 5 additions & 5 deletions cpu/core.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
This core module takes decoded instructions and produces output data
*/

module tinyqv_core #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
module tinyqv_core #(parameter XLEN=32, parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
input clk,
input rstn,

Expand Down Expand Up @@ -85,9 +85,9 @@ module tinyqv_core #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
reg [3:0] data_rd;
reg wr_en;

reg [31:0] tmp_data;
reg [XLEN-1:0] tmp_data;

tinyqv_registers #(.REG_ADDR_BITS(REG_ADDR_BITS), .NUM_REGS(NUM_REGS))
tinyqv_registers #(.XLEN(XLEN), .NUM_REGS(NUM_REGS), .REG_ADDR_BITS(REG_ADDR_BITS))
i_registers(clk, rstn, wr_en, counter, rs1, rs2, rd, data_rs1, data_rs2, data_rd, return_addr);


Expand Down Expand Up @@ -258,7 +258,7 @@ module tinyqv_core #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (

always @(posedge clk) begin
if (tmp_data_shift)
tmp_data <= {tmp_data_in, tmp_data[31:4]};
tmp_data <= {tmp_data_in, tmp_data[XLEN-1:4]};
end

assign addr_out = is_mret ? {4'b0000, mepc} : tmp_data[31:4];
Expand Down Expand Up @@ -299,7 +299,7 @@ module tinyqv_core #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
instr_retired <= instr_complete && !is_stall;
end
/* verilator lint_off PINMISSING */ // No carry
tinyqv_counter i_instrret (
tinyqv_counter #(.OUTPUT_WIDTH(4)) i_instrret (
.clk(clk),
.rstn(rstn),
.add(instr_retired),
Expand Down
6 changes: 3 additions & 3 deletions cpu/cpu.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
This CPU module interfaces with memory, the instruction decoder and the core.
*/

module tinyqv_cpu #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
module tinyqv_cpu #(parameter XLEN=32, parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
input clk,
input rstn,

Expand Down Expand Up @@ -69,7 +69,7 @@ module tinyqv_cpu #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
wire [2:0] additional_mem_ops_de;
wire mem_op_increment_reg_de;

tinyqv_decoder i_decoder(
tinyqv_decoder #(.XLEN(XLEN), .REG_ADDR_BITS(REG_ADDR_BITS)) i_decoder(
.instr(instr),
.imm(imm_de),

Expand Down Expand Up @@ -302,7 +302,7 @@ module tinyqv_cpu #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
was_early_branch <= early_branch && !branch;
end

tinyqv_core #(.REG_ADDR_BITS(REG_ADDR_BITS), .NUM_REGS(NUM_REGS)) i_core(
tinyqv_core #(.XLEN(XLEN), .NUM_REGS(NUM_REGS), .REG_ADDR_BITS(REG_ADDR_BITS)) i_core(
.clk(clk),
.rstn(rstn),

Expand Down
38 changes: 19 additions & 19 deletions cpu/decode.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
Note parts of this are from the excellent FemtoRV by Bruno Levy et al.
*/

module tinyqv_decoder #(parameter REG_ADDR_BITS=4) (
module tinyqv_decoder #(parameter XLEN=32, parameter REG_ADDR_BITS=4) (
input [31:0] instr,

output reg [31:0] imm,
output reg [XLEN-1:0] imm,

output reg is_load,
output reg is_alu_imm,
Expand Down Expand Up @@ -34,25 +34,25 @@ module tinyqv_decoder #(parameter REG_ADDR_BITS=4) (
output reg mem_op_increment_reg
);

wire [31:0] Uimm = { instr[31], instr[30:12], {12{1'b0}}};
wire [31:0] Iimm = {{21{instr[31]}}, instr[30:20]};
wire [31:0] Simm = {{21{instr[31]}}, instr[30:25],instr[11:7]};
wire [31:0] Bimm = {{20{instr[31]}}, instr[7],instr[30:25],instr[11:8],1'b0};
wire [31:0] Jimm = {{12{instr[31]}}, instr[19:12],instr[20],instr[30:21],1'b0};
wire [XLEN-1:0] Uimm = {{XLEN-31{instr[31]}}, instr[30:12], {12{1'b0}}};
wire [XLEN-1:0] Iimm = {{XLEN-11{instr[31]}}, instr[30:20]};
wire [XLEN-1:0] Simm = {{XLEN-11{instr[31]}}, instr[30:25],instr[11:7]};
wire [XLEN-1:0] Bimm = {{XLEN-12{instr[31]}}, instr[7],instr[30:25],instr[11:8],1'b0};
wire [XLEN-1:0] Jimm = {{XLEN-20{instr[31]}}, instr[19:12],instr[20],instr[30:21],1'b0};

// Compressed immediates
wire [31:0] CLWSPimm = {24'b0, instr[3:2], instr[12], instr[6:4], 2'b00};
wire [31:0] CSWSPimm = {24'b0, instr[8:7], instr[12:9], 2'b00};
wire [31:0] CLSWimm = {25'b0, instr[5], instr[12:10], instr[6], 2'b00}; // LW and SW
wire [31:0] CLSHimm = {30'b0, instr[5], 1'b0}; // LH(U) and SH
wire [31:0] CLSBimm = {30'b0, instr[5], instr[6]}; // LBU and SB
wire [31:0] CJimm = {{21{instr[12]}}, instr[8], instr[10:9], instr[6], instr[7], instr[2], instr[11], instr[5:3], 1'b0};
wire [31:0] CBimm = {{24{instr[12]}}, instr[6:5], instr[2], instr[11:10], instr[4:3], 1'b0};
wire [31:0] CALUimm = {{27{instr[12]}}, instr[6:2]}; // ADDI, LI, shifts, ANDI
wire [31:0] CLUIimm = {{15{instr[12]}}, instr[6:2], 12'b0};
wire [31:0] CADDI16SPimm = {{23{instr[12]}}, instr[4:3], instr[5], instr[2], instr[6], 4'b0};
wire [31:0] CADDI4SPimm = {22'b0, instr[10:7], instr[12:11], instr[5], instr[6], 2'b0};
wire [31:0] CSCXTimm = {{23{instr[12]}}, instr[9:7], instr[10], instr[11], 4'b0};
wire [XLEN-1:0] CLWSPimm = {{XLEN-8{1'b0}}, instr[3:2], instr[12], instr[6:4], 2'b00};
wire [XLEN-1:0] CSWSPimm = {{XLEN-8{1'b0}}, instr[8:7], instr[12:9], 2'b00};
wire [XLEN-1:0] CLSWimm = {{XLEN-7{1'b0}}, instr[5], instr[12:10], instr[6], 2'b00}; // LW and SW
wire [XLEN-1:0] CLSHimm = {{XLEN-2{1'b0}}, instr[5], 1'b0}; // LH(U) and SH
wire [XLEN-1:0] CLSBimm = {{XLEN-2{1'b0}}, instr[5], instr[6]}; // LBU and SB
wire [XLEN-1:0] CJimm = {{XLEN-11{instr[12]}}, instr[8], instr[10:9], instr[6], instr[7], instr[2], instr[11], instr[5:3], 1'b0};
wire [XLEN-1:0] CBimm = {{XLEN-8{instr[12]}}, instr[6:5], instr[2], instr[11:10], instr[4:3], 1'b0};
wire [XLEN-1:0] CALUimm = {{XLEN-5{instr[12]}}, instr[6:2]}; // ADDI, LI, shifts, ANDI
wire [XLEN-1:0] CLUIimm = {{XLEN-17{instr[12]}}, instr[6:2], 12'b0};
wire [XLEN-1:0] CADDI16SPimm = {{XLEN-9{instr[12]}}, instr[4:3], instr[5], instr[2], instr[6], 4'b0};
wire [XLEN-1:0] CADDI4SPimm = {{XLEN-10{1'b0}}, instr[10:7], instr[12:11], instr[5], instr[6], 2'b0};
wire [XLEN-1:0] CSCXTimm = {{XLEN-9{instr[12]}}, instr[9:7], instr[10], instr[11], 4'b0};

always @(*) begin
additional_mem_ops = 3'b000;
Expand Down
18 changes: 9 additions & 9 deletions cpu/register.v
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
The read bit address is one ahead of write bit address, and both increment every clock.
*/

module tinyqv_registers #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
module tinyqv_registers #(parameter XLEN=32, parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
input clk,
input rstn,

Expand All @@ -26,7 +26,7 @@ module tinyqv_registers #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
output [23:1] return_addr
);

reg [31:0] registers [1:NUM_REGS-1];
reg [XLEN-1:0] registers [1:NUM_REGS-1];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some 31s further down that will need fixing.

wire [3:0] reg_access [0:2**REG_ADDR_BITS-1];

genvar i;
Expand All @@ -46,22 +46,22 @@ module tinyqv_registers #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
registers[i][3:0] <= registers[i][7:4];
end

wire [31:4] reg_buf;
wire [XLEN-1:4] reg_buf;
`ifdef SIM
/* verilator lint_off ASSIGNDLY */
buf #1 i_regbuf[31:4] (reg_buf, {registers[i][3:0], registers[i][31:8]});
buf #1 i_regbuf[XLEN-1:4] (reg_buf, {registers[i][3:0], registers[i][XLEN-1:8]});
/* verilator lint_on ASSIGNDLY */
`elsif ICE40
assign reg_buf = {registers[i][3:0], registers[i][31:8]};
assign reg_buf = {registers[i][3:0], registers[i][XLEN-1:8]};
`elsif SCL_sky130_fd_sc_hd
/* verilator lint_off PINMISSING */
sky130_fd_sc_hd__dlygate4sd3_1 i_regbuf[31:4] ( .X(reg_buf), .A({registers[i][3:0], registers[i][31:8]}) );
sky130_fd_sc_hd__dlygate4sd3_1 i_regbuf[XLEN-1:4] ( .X(reg_buf), .A({registers[i][3:0], registers[i][XLEN-1:8]}) );
/* verilator lint_on PINMISSING */
`else
// On SG13G2 no buffer is required, use direct assignment
assign reg_buf = {registers[i][3:0], registers[i][31:8]};
assign reg_buf = {registers[i][3:0], registers[i][XLEN-1:8]};
`endif
always @(posedge clk) registers[i][31:4] <= reg_buf;
always @(posedge clk) registers[i][XLEN-1:4] <= reg_buf;

assign reg_access[i] = registers[i][7:4];
end
Expand All @@ -71,7 +71,7 @@ module tinyqv_registers #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
assign data_rs1 = reg_access[rs1];
assign data_rs2 = reg_access[rs2];

assign return_addr = registers[1][31:9];
assign return_addr = registers[1][XLEN-1:9];

wire _unused = &{rstn, 1'b0};

Expand Down
4 changes: 2 additions & 2 deletions cpu/tinyqv.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
`default_nettype none

// TinyQV CPU and QSPI memory controller wrapper
module tinyQV (
module tinyQV #(parameter XLEN=32, parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
input clk,
input rstn,

Expand Down Expand Up @@ -91,7 +91,7 @@ module tinyQV (
reg rst_reg_n;
always @(posedge clk) rst_reg_n <= rstn;

tinyqv_cpu cpu(
tinyqv_cpu #(.XLEN(XLEN), .NUM_REGS(NUM_REGS), .REG_ADDR_BITS(REG_ADDR_BITS)) cpu(
.clk(clk),
.rstn(rst_reg_n),

Expand Down
2 changes: 1 addition & 1 deletion iceFUN/iceFUN.v
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ module tinyQV_top (
wire data_ready;
reg [31:0] data_from_read;

tinyQV i_tinyqv(
tinyQV #(.XLEN(32), .NUM_REGS(16), .REG_ADDR_BITS(4)) i_tinyqv(
.clk(clk),
.rstn(rst_reg_n),

Expand Down
2 changes: 1 addition & 1 deletion pico_ice/pico_ice.v
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ module tinyQV_top (
wire debug_stop_txn;
wire [3:0] debug_rd;

tinyQV i_tinyqv(
tinyQV #(.XLEN(32), .NUM_REGS(16), .REG_ADDR_BITS(4)) i_tinyqv(
.clk(clk),
.rstn(rst_reg_n),

Expand Down
14 changes: 12 additions & 2 deletions test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,17 @@
make -f test_$*.mk
mv results.xml $@

all: clean alu-results.xml core-results.xml counter-results.xml cpu-results.xml decode-results.xml mem_ctrl-results.xml qspi_ctrl-results.xml register-results.xml
%-results-32.xml:
make XLEN=32 -f test_$*.mk clean
make XLEN=32 -f test_$*.mk
mv results.xml $@

%-results-64.xml:
make XLEN=64 -f test_$*.mk clean
make XLEN=64 -f test_$*.mk
mv results.xml $@

all: clean alu-results.xml core-results.xml counter-results.xml cpu-results.xml decode-results-32.xml decode-results-64.xml mem_ctrl-results.xml qspi_ctrl-results.xml register-results.xml

clean:
rm *results.xml || true
rm *results.xml *results-32.xml *results-64.xml || true
6 changes: 3 additions & 3 deletions test/tb_core.v
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ end
wire [2:0] additional_mem_ops;
wire mem_op_increment_reg;

tinyqv_decoder decoder(instr,
tinyqv_decoder #(.XLEN(32), .REG_ADDR_BITS(4)) decoder(instr,
imm,

is_load,
Expand Down Expand Up @@ -108,7 +108,7 @@ end
wire debug_reg_wen;
wire [3:0] debug_rd;

tinyqv_core core(clk,
tinyqv_core #(.XLEN(32), .NUM_REGS(16), .REG_ADDR_BITS(4)) core(clk,
rstn,

imm[counter+:4],
Expand Down Expand Up @@ -155,4 +155,4 @@ end
debug_rd
);

endmodule
endmodule
4 changes: 2 additions & 2 deletions test/tb_counter.v
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ end
end

wire [3:0] data;
tinyqv_counter i_mcount(clk, rstn, add, last_counter[4:2], data, cy_out);
tinyqv_counter #(.OUTPUT_WIDTH(4)) i_mcount(clk, rstn, add, last_counter[4:2], data, cy_out);

always @(posedge clk) begin
val[last_counter+:4] <= data;
if (last_counter[4:2] == 3'b111) cy <= cy_out;
end

endmodule
endmodule
2 changes: 1 addition & 1 deletion test/tb_cpu.v
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ end
wire debug_counter_0;
wire [3:0] debug_rd;

tinyqv_cpu cpu(
tinyqv_cpu #(.XLEN(32), .NUM_REGS(16), .REG_ADDR_BITS(4)) cpu(
clk,
rstn,

Expand Down
8 changes: 4 additions & 4 deletions test/tb_decode.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
Aim is to support RV32E
*/

module tb_decode (
module tb_decode #(parameter XLEN=32) (
input clk,
input rstn,

input [31:0] instr,

output [31:0] imm,
output [XLEN-1:0] imm,

output is_load,
output is_alu_imm,
Expand Down Expand Up @@ -44,7 +44,7 @@ initial begin
end
`endif

tinyqv_decoder decoder(instr,
tinyqv_decoder #(.XLEN(XLEN), .REG_ADDR_BITS(4)) decoder(instr,
imm,

is_load,
Expand Down Expand Up @@ -74,4 +74,4 @@ end

assign instr_len[0] = 1'b0;

endmodule
endmodule
4 changes: 2 additions & 2 deletions test/tb_qspi_flash.v
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ initial begin
end
`endif

qspi_flash_controller i_flash(
qspi_flash_controller #(.DATA_WIDTH_BYTES(2), .ADDR_BITS(24)) i_flash(
clk,
rstn,

Expand All @@ -53,4 +53,4 @@ end
busy
);

endmodule
endmodule
5 changes: 3 additions & 2 deletions test/tb_register.v
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ end
wire [3:0] data_rs1;
wire [3:0] data_rs2;
wire [23:1] return_addr;
tinyqv_registers registers(clk, rstn, wr_en, last_counter[4:2], rs1, rs2, rd, data_rs1, data_rs2, rd_in[last_counter+:4], return_addr);
tinyqv_registers #(.XLEN(32), .NUM_REGS(16), .REG_ADDR_BITS(4))
registers(clk, rstn, wr_en, last_counter[4:2], rs1, rs2, rd, data_rs1, data_rs2, rd_in[last_counter+:4], return_addr);

always @(posedge clk) begin
rs1_out[last_counter+:4] <= data_rs1;
rs2_out[last_counter+:4] <= data_rs2;
end

endmodule
endmodule
4 changes: 2 additions & 2 deletions test/test_decode.mk
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ TOPLEVEL_LANG ?= verilog

CPUD = $(PWD)/../cpu
VERILOG_SOURCES += $(CPUD)/decode.v $(PWD)/tb_decode.v
COMPILE_ARGS += -DSIM
COMPILE_ARGS += -DSIM -Ptb_decode.XLEN=$(XLEN)

# TOPLEVEL is the name of the toplevel module in your Verilog or VHDL file
TOPLEVEL = tb_decode
Expand All @@ -16,4 +16,4 @@ TOPLEVEL = tb_decode
MODULE = test_decode

# include cocotb's make rules to take care of the simulator setup
include $(shell cocotb-config --makefiles)/Makefile.sim
include $(shell cocotb-config --makefiles)/Makefile.sim
Loading