-
Notifications
You must be signed in to change notification settings - Fork 7
/
tt_um_riscv_shell.tlv
190 lines (146 loc) · 6.65 KB
/
tt_um_riscv_shell.tlv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
\m5_TLV_version 1d: tl-x.org
\m5
use(m5-1.0)
// #################################################################
// # #
// # Starting-Point Code for MEST Course Tiny Tapeout RISC-V CPU #
// # #
// #################################################################
// ========
// Settings
// ========
var(my_design, tt_um_example) /// The name of your top-level TT module, to match your info.yml.
var(debounce_inputs, 0)
/// Legal values:
/// 1: Provide synchronization and debouncing on all input signals.
/// 0: Don't provide synchronization and debouncing.
/// m5_if_defined_as(MAKERCHIP, 1, 0, 1): Debounce unless in Makerchip.
var(in_fpga, 1) /// For Makerchip development: 1 to include the demo board in VIZ (in which case, logic will be under /fpga_pins/fpga).
// CPU configs
var(num_regs, 16) /// 32 for full reg file.
var(dmem_size, 8) /// Size of DMem, a power of 2.
// ======================
// Computed From Settings
// ======================
// If debouncing, a user's module is within a wrapper, so it has a different name.
var(user_module_name, m5_if(m5_debounce_inputs, my_design, m5_my_design))
var(debounce_cnt, m5_if_defined_as(MAKERCHIP, 1, 8'h03, 8'hff))
// ==================
// Sum 1 to 9 Program
// ==================
TLV_fn(riscv_sum_prog, {
~assemble(['
# Add 1,2,3,...,9 (in that order).
#
# Regs:
# x10 (a0): In: 0, Out: final sum
# x12 (a2): 10
# x13 (a3): 1..10
# x14 (a4): Sum
#
# External to function:
reset:
ADD x10, x0, x0 # Initialize r10 (a0) to 0.
# Function:
ADD x14, x10, x0 # Initialize sum register a4 with 0x0
ADDI x12, x10, 10 # Store count of 10 in register a2.
ADD x13, x10, x0 # Initialize intermediate sum register a3 with 0
loop:
ADD x14, x13, x14 # Incremental addition
ADDI x13, x13, 1 # Increment count register by 1
BLT x13, x12, loop # If a3 is less than a2, branch to label named <loop>
done:
ADD x10, x14, x0 # Store final result to register a0 so that it can be read by main program
'])
})
\SV
// =================
// Include Libraries
// =================
// Tiny Tapeout Lab.
m4_include_lib(['https:/']['/raw.githubusercontent.com/os-fpga/Virtual-FPGA-Lab/35e36bd144fddd75495d4cbc01c4fc50ac5bde6f/tlv_lib/tiny_tapeout_lib.tlv'])
// RISC-V CPU VIZ.
m4_include_lib(['https://raw.githubusercontent.com/efabless/chipcraft---mest-course/main/tlv_lib/risc-v_shell_lib.tlv'])
\TLV cpu()
m5+riscv_gen()
m5+riscv_sum_prog()
m5_define_hier(IMEM, m5_NUM_INSTRS)
|cpu
@0
$reset = *reset;
// ==================
// | |
// | YOUR CODE HERE |
// | |
// ==================
// Note that pipesignals assigned here can be found under /fpga_pins/fpga (if in_fpga is set to 1 above).
// Assert these to end simulation (before Makerchip cycle limit).
// Note, for Makerchip simulation these are passed in uo_out to top-level module's passed/failed signals.
*passed = *top.cyc_cnt > 40;
*failed = 1'b0;
// Connect Tiny Tapeout outputs. Note that uio_ outputs are not available in the Tiny-Tapeout-3-based FPGA boards.
*uo_out = {6'b0, *failed, *passed};
*uio_out = 8'b0;
*uio_oe = 8'b0;
// Macro instantiations to be uncommented when instructed for:
// o instruction memory
// o register file
// o data memory
// o CPU visualization
|cpu
///m5+imem(@1) // Args: (read stage)
///m5+rf(@1, @1) // Args: (read stage, write stage) - if equal, no register bypass is required
///m5+dmem(@4) // Args: (read/write stage)
///m5+cpu_viz(@4) // For visualization, argument should be at least equal to the last stage of CPU logic. @4 would work for all labs.
\SV
// ================================================
// A simple Makerchip Verilog test bench driving random stimulus.
// Modify the module contents to your needs.
// ================================================
module top(input logic clk, input logic reset, input logic [31:0] cyc_cnt, output logic passed, output logic failed);
// Tiny tapeout I/O signals.
logic [7:0] ui_in, uio_in, uo_out, uio_out, uio_oe;
logic [31:0] r; // a random value
always @(posedge clk) r <= m5_if_defined_as(MAKERCHIP, 1, ['$urandom()'], ['0']);
assign ui_in = r[7:0];
assign uio_in = 8'b0;
logic ena = 1'b0;
logic rst_n = ! reset;
// Instantiate the Tiny Tapeout module.
m5_user_module_name tt(.*);
// Passed/failed to control Makerchip simulation, passed from Tiny Tapeout module's uo_out pins.
assign passed = uo_out[0];
assign failed = uo_out[1];
endmodule
// Provide a wrapper module to debounce input signals if requested.
m5_if(m5_debounce_inputs, ['m5_tt_top(m5_my_design)'])
\SV
// =======================
// The Tiny Tapeout module
// =======================
module m5_user_module_name (
input wire [7:0] ui_in, // Dedicated inputs - connected to the input switches
output wire [7:0] uo_out, // Dedicated outputs - connected to the 7 segment display
input wire [7:0] uio_in, // IOs: Bidirectional Input path
output wire [7:0] uio_out, // IOs: Bidirectional Output path
output wire [7:0] uio_oe, // IOs: Bidirectional Enable path (active high: 0=input, 1=output)
input wire ena, // will go high when the design is enabled
input wire clk, // clock
input wire rst_n // reset_n - low to reset
);
logic passed, failed; // Connected to uo_out[0] and uo_out[1] respectively, which connect to Makerchip passed/failed.
wire reset = ! rst_n;
// List all potentially-unused inputs to prevent warnings
wire _unused = &{ena, 1'b0};
\TLV tt_lab()
// Connect Tiny Tapeout I/Os to Virtual FPGA Lab.
m5+tt_connections()
// Instantiate the Virtual FPGA Lab.
m5+board(/top, /fpga, 7, $, , cpu)
// Label the switch inputs [0..7] (1..8 on the physical switch panel) (top-to-bottom).
m5+tt_input_labels_viz(['"UNUSED", "UNUSED", "UNUSED", "UNUSED", "UNUSED", "UNUSED", "UNUSED", "UNUSED"'])
\TLV
/* verilator lint_off UNOPTFLAT */
m5_if(m5_in_fpga, ['m5+tt_lab()'], ['m5+cpu()'])
\SV
endmodule