Skip to content

Commit 94fe33a

Browse files
committed
Add gf180 scratch RAM
1 parent 2d73fdb commit 94fe33a

5 files changed

Lines changed: 91 additions & 4 deletions

File tree

cpu/config.vlt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
`verilator_config
2+
lint_off -file "*/gf180mcu_fd_ip_sram__sram512x8m8wm1.v"
3+
lint_off -rule MINTYPMAXDLY -file "*/gf180mcu_fd_ip_sram__sram512x8m8wm1.v"
4+
lint_off -rule SPECIFYIGN -file "*/gf180mcu_fd_ip_sram__sram512x8m8wm1.v"
5+

cpu/cpu.v

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,11 @@ module tinyqv_cpu #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
145145
wire [3:0] timer_data;
146146
wire is_timer_addr;
147147

148+
wire [3:0] scratch_data;
149+
wire is_scratch_addr;
150+
151+
wire is_internal_addr = is_timer_addr || is_scratch_addr;
152+
148153
reg no_write_in_progress;
149154
reg load_started;
150155
wire stall_core = !instr_valid || ((is_store || is_load) && !no_write_in_progress);
@@ -244,7 +249,7 @@ module tinyqv_cpu #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
244249

245250
if (counter_hi == 3'd0) begin
246251
data_ready_latch <= 0;
247-
if (data_ready_ext || data_ready_latch || is_timer_addr) begin
252+
if (data_ready_ext || data_ready_latch || is_internal_addr) begin
248253
data_ready_sync <= 1;
249254
end else begin
250255
data_ready_sync <= 0;
@@ -257,7 +262,7 @@ module tinyqv_cpu #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
257262
end
258263
end
259264

260-
assign data_ready_core = (counter_hi == 3'd0) ? (data_ready_ext || data_ready_latch || is_timer_addr) : data_ready_sync;
265+
assign data_ready_core = (counter_hi == 3'd0) ? (data_ready_ext || data_ready_latch || is_internal_addr) : data_ready_sync;
261266

262267
always @(posedge clk) begin
263268
if (!rstn) begin
@@ -351,7 +356,8 @@ module tinyqv_cpu #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
351356
.counter(counter[4:2]),
352357
.pc(pc[counter+:4]),
353358
.next_pc(next_pc_for_core[counter+:4]),
354-
.data_in(is_timer_addr ? timer_data : data_in[counter+:4]),
359+
.data_in(is_timer_addr ? timer_data :
360+
is_scratch_addr ? scratch_data : data_in[counter+:4]),
355361
.load_data_ready(data_ready_core),
356362

357363
.data_out(data_out_slice),
@@ -462,6 +468,24 @@ module tinyqv_cpu #(parameter NUM_REGS=16, parameter REG_ADDR_BITS=4) (
462468
.timer_interrupt(timer_interrupt)
463469
);
464470

471+
`ifdef NO_SCRATCH
472+
assign is_scratch_addr = 0;
473+
assign scratch_data = 0;
474+
`else
475+
// Scratch
476+
assign is_scratch_addr = data_addr[27:12] == 16'hffff && data_addr[11:9] == 3'b110;
477+
wire [1:0] scratch_write_n = data_write_n | {2{!is_scratch_addr}};
478+
tinyqv_scratch i_scratch (
479+
.clk(clk),
480+
.rstn(rstn),
481+
.data_addr(address_ready ? addr_out[8:0] : data_addr[8:0]),
482+
.data_write_n(scratch_write_n),
483+
.counter(counter_hi),
484+
.data_in(data_out_slice),
485+
.data_out(scratch_data)
486+
);
487+
`endif
488+
465489
// Debugging
466490
assign debug_instr_complete = instr_complete;
467491
assign debug_instr_valid = instr_valid;

cpu/internal_ram.v

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* TinyQV: A RISC-V core designed to use minimal area.
2+
3+
This module wraps an SRAM primitive to provide scratch RAM.
4+
5+
This version wraps the gf180 primitive.
6+
*/
7+
8+
`default_nettype none
9+
10+
module tinyqv_scratch #(parameter ADDR_BITS=9) (
11+
input clk,
12+
input rstn,
13+
14+
input [ADDR_BITS-1:0] data_addr,
15+
input [1:0] data_write_n,
16+
input [2:0] counter,
17+
18+
input [3:0] data_in,
19+
output [3:0] data_out
20+
);
21+
22+
wire write_enable_n;
23+
wire [7:0] write_bit_enable_n;
24+
wire [7:0] data_from_read;
25+
wire [1:0] byte_in_word;
26+
27+
/* verilator lint_off PINMISSING */
28+
gf180mcu_fd_ip_sram__sram512x8m8wm1 i_sram (
29+
.CLK(clk),
30+
.CEN(!rstn),
31+
.GWEN(write_enable_n),
32+
.WEN(write_bit_enable_n),
33+
.A({data_addr[ADDR_BITS-1:2], byte_in_word}),
34+
.D({data_in, data_in}),
35+
.Q(data_from_read)
36+
);
37+
/* verilator lint_on PINMISSING */
38+
39+
assign data_out = counter[0] ? data_from_read[7:4] : data_from_read[3:0];
40+
41+
assign write_enable_n =
42+
!((data_write_n == 2'b00 && counter[2:1] == 2'b00) ||
43+
(data_write_n == 2'b01 && !counter[2]) ||
44+
(data_write_n == 2'b10));
45+
46+
assign write_bit_enable_n = {{4{!counter[0]}}, {4{counter[0]}}};
47+
48+
// Byte address:
49+
// - For writes this should be the data address + the counter/2 (as the counter counts in nibbles)
50+
// - For reads this needs to give the correct address to read the nibble on the next cycle.
51+
// Therefore, increment by 1 on the second half of each byte.
52+
// Note the first byte is read on the last count of the previous cycle (this is OK because the
53+
// address is already complete by then).
54+
// Can use XOR instead of ADD because we assume the address is aligned for the width of the transaction.
55+
assign byte_in_word = (counter[2:1] + {1'b0, counter[0] && (data_write_n == 2'b11)}) ^ data_addr[1:0];
56+
57+
endmodule

cpu/lint.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#!/bin/bash
22

3-
verilator --lint-only -DSIM --timing -Wall -Wno-DECLFILENAME -Wno-MULTITOP *.v
3+
verilator --lint-only -DSIM --timing -Wall -Wno-DECLFILENAME -Wno-MULTITOP -Wno-TIMESCALEMOD config.vlt *.v $PDK_ROOT/gf180mcuD/libs.ref/gf180mcu_fd_ip_sram/verilog/gf180mcu_fd_ip_sram__sram512x8m8wm1.v

test/test_cpu.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ TOPLEVEL_LANG ?= verilog
88
CPUD = $(PWD)/../cpu
99
VERILOG_SOURCES += $(CPUD)/cpu.v $(CPUD)/decode.v $(CPUD)/core.v $(CPUD)/alu.v $(CPUD)/register.v $(CPUD)/counter.v $(CPUD)/time.v $(CPUD)/buffer.v $(PWD)/tb_cpu.v
1010
COMPILE_ARGS += -DSIM
11+
COMPILE_ARGS += -DNO_SCRATCH
1112

1213
# TOPLEVEL is the name of the toplevel module in your Verilog or VHDL file
1314
TOPLEVEL = tb_cpu

0 commit comments

Comments
 (0)