@@ -19,11 +19,11 @@ The SOC instantiates six major components:
19
19
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=208-213) -->
20
20
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
21
21
``` c
22
- // RAM for CPU (SPRAM)
23
- bram_port_io mem_io_ram;
24
- bram_spram_32bits bram_ram (
25
- pram <:> mem_io_ram
26
- );
22
+ // ==============================
23
+ // CPU
24
+ uint32 user_data (0);
25
+ bram_port_io mem_io_cpu;
26
+ rv32i_cpu cpu(
27
27
```
28
28
<!-- MARKDOWN-AUTO-DOCS:END -->
29
29
@@ -32,13 +32,13 @@ The SOC instantiates six major components:
32
32
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=215-221) -->
33
33
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
34
34
```c
35
- // CPU
36
- uint32 user_data(0);
37
- bram_port_io mem_io_cpu;
38
- rv32i_cpu cpu(
39
- user_data <:: user_data,
40
35
mem <:> mem_io_cpu,
41
36
);
37
+
38
+ // ==============================
39
+ // GPU
40
+ texmem_io txm_io;
41
+ DMC_1_gpu gpu(txm <:> txm_io,
42
42
```
43
43
<!-- MARKDOWN-AUTO-DOCS:END -->
44
44
@@ -47,10 +47,11 @@ The SOC instantiates six major components:
47
47
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=224-228) -->
48
48
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
49
49
``` c
50
- // GPU
51
- texmem_io txm_io;
52
- DMC_1_gpu gpu (txm <:> txm_io,
53
- screen_ready <: screen_ctrl.ready);
50
+ // ==============================
51
+ // screen display
52
+ uint1 screen_valid (0); uint1 screen_ready(0);
53
+ uint1 screen_send_dc(0); uint8 screen_send_byte(0);
54
+ screen_controller screen_ctrl(
54
55
```
55
56
<!-- MARKDOWN-AUTO-DOCS:END -->
56
57
@@ -59,13 +60,13 @@ The SOC instantiates six major components:
59
60
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=274-280) -->
60
61
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
61
62
```c
62
- // texture memory
63
- $if MCH2022 or (SIMULATION and SIMUL_QPSRAM) then
64
- qpsram_ram txm<@clock2x,!rst2x,reginputs> (
65
- ram_clk :> ram_clk, ram_csn :> ram_csn,
66
- ram_io0 <:> ram_io0, ram_io1 <:> ram_io1,
67
63
ram_io2 <:> ram_io2, ram_io3 <:> ram_io3,
68
64
);
65
+ $else -- not MCH2022
66
+ spiflash_rom_core txm<@clock2x,!rst2x,reginputs> (
67
+ sf_clk :> sf_clk, sf_csn :> sf_csn,
68
+ sf_io0 <:> sf_io0, sf_io1 <:> sf_io1,
69
+ sf_io2 <:> sf_io2, sf_io3 <:> sf_io3,
69
70
```
70
71
<!-- MARKDOWN-AUTO-DOCS:END -->
71
72
@@ -74,8 +75,7 @@ $if MCH2022 or (SIMULATION and SIMUL_QPSRAM) then
74
75
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=336-338) -->
75
76
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
76
77
``` c
77
- // command queue
78
- command_queue cmdq (current :> gpu.command);
78
+ always {
79
79
```
80
80
<!-- MARKDOWN-AUTO-DOCS:END -->
81
81
@@ -84,16 +84,17 @@ $if MCH2022 or (SIMULATION and SIMUL_QPSRAM) then
84
84
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=230-240) -->
85
85
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
86
86
```c
87
- // screen display
88
- uint1 screen_valid(0); uint1 screen_ready(0);
89
- uint1 screen_send_dc(0); uint8 screen_send_byte(0);
90
- screen_controller screen_ctrl(
91
- screen_valid :> screen_valid,
92
87
screen_ready <: screen_ready,
93
88
send_dc :> screen_send_dc,
94
89
send_byte :> screen_send_byte,
95
90
);
96
91
// ...
92
+
93
+ $if MCH2022 then
94
+ screen_driver screen(
95
+ ready :> screen_ready,
96
+ screen_d :> lcd_d,
97
+ screen_dc :> lcd_rs,
97
98
```
98
99
<!-- MARKDOWN-AUTO-DOCS:END -->
99
100
@@ -161,23 +162,24 @@ First, note that the GPU is bound to a `texmem_io` group called `txm_io`:
161
162
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=224-228) -->
162
163
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
163
164
```c
164
- // GPU
165
- texmem_io txm_io;
166
- DMC_1_gpu gpu(txm <:> txm_io,
167
- screen_ready <: screen_ctrl.ready);
165
+ // ==============================
166
+ // screen display
167
+ uint1 screen_valid(0); uint1 screen_ready(0);
168
+ uint1 screen_send_dc(0); uint8 screen_send_byte(0);
169
+ screen_controller screen_ctrl(
168
170
```
169
171
<!-- MARKDOWN-AUTO-DOCS:END -->
170
172
171
173
These variables are updated in the always block:
172
174
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=366-371) -->
173
175
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
174
176
``` c
175
- // track texture memory interface
176
- dataAvail.valid = txm_io.in_ready | txm_burst_read_active;
177
- txm.in_ready = txm_io.in_ready | txm_burst_read_active;
178
- txm.addr = txm_burst_read_active ? txm.addr : txm_io.addr;
179
- txm_io.data = txm.rdata;
180
177
txm_io.busy = txm.busy;
178
+ $if MCH2022 then
179
+ txm.wenable = 0 ; // we never write to PSRAM
180
+ $end
181
+ $if SIMULATION then
182
+ // if ((|mem_io_ram.wenable) & txm_burst_data_available) {
181
183
```
182
184
<!-- MARKDOWN-AUTO-DOCS:END -->
183
185
As you can see, this connects ` txm_io ` to ` txm ` which is the flash memory unit itself:
@@ -188,11 +190,6 @@ transfer:
188
190
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=449-472) -->
189
191
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
190
192
``` c
191
- case 2b10: { // texture memory CPU read
192
- // NOTE1: assumes there cannot be collisions with
193
- // the texture sampler ; CPU should not drive
194
- // texture memory while draw calls are pending
195
- // NOTE2: CPU cannot write to RAM while the burst occurs,
196
193
// and should wait on user_data, txm.busy bit
197
194
// NOTE3: destination addresses have to be 32-bits aligned
198
195
uint1 len_else_dst = prev_mem_wdata[31 ,1 ];
@@ -212,6 +209,11 @@ transfer:
212
209
txm.addr = prev_mem_wdata[0,24];
213
210
txm_burst_read_active = src_and_trigger; // start
214
211
txm_burst_data_cursor = 5b10000;
212
+ $if SIMULATION then
213
+ //if (src_and_trigger) {
214
+ // __ display("[ cycle %d] BURST start, from @%x to @%x, len %d",iter,txm.addr,txm_burst_read_dst<<2,txm_burst_len);
215
+ //}
216
+ $end
215
217
```
216
218
<!-- MARKDOWN-AUTO-DOCS:END -->
217
219
@@ -220,8 +222,8 @@ RAM is being written every cycle and it can no longer fetch instruction.
220
222
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=380-381) -->
221
223
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
222
224
```c
223
- // stall CPU on bursts
224
- cpu.stall_cpu = txm_burst_read_active;
225
+ : txm_burst_data;
226
+ txm_burst_data_cursor =
225
227
```
226
228
<!-- MARKDOWN-AUTO-DOCS:END -->
227
229
@@ -237,17 +239,17 @@ memory. Because each command is 64 bits, this takes two memory writes:
237
239
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=482-492) -->
238
240
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
239
241
``` c
240
- case 4b0001: { // GPU commands
241
- if (prev_mem_addr[ 0,1] ) {
242
- // received first half
243
- cmdq.in_command[ 32,32] = prev_mem_wdata[ 0,32] ;
244
- } else {
245
242
// received second half
246
243
cmdq.in_command[ 0 ,32 ] = prev_mem_wdata[0 ,32 ];
247
244
// store in fifo
248
245
cmdq.in_add = 1 ;
249
246
}
250
247
}
248
+ case 4b1000: { // GPU commands in part
249
+ switch (prev_mem_addr[ 6,4] ) {
250
+ // tex0 PARAMETER_PLANE_A (2<<30) | ((ny) & 1023) | (((uy) & 1023)<<10) | (((vy) & 1023)<<20)
251
+ case 0: { // PARAMETER_PLANE_A_ny
252
+ cmdq.in_command[ $32+ 0$,10] = prev_mem_wdata[ 0,10] ;
251
253
```
252
254
<!-- MARKDOWN-AUTO-DOCS:END -->
253
255
@@ -258,9 +260,9 @@ memory space):
258
260
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=415-417) -->
259
261
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
260
262
```c
261
- // memory mapping
262
- if ((prev_mem_wenable != 0) & prev_mem_addr[16,1]) {
263
- switch (prev_mem_addr[2,4]) {
263
+ uo.data_in = prev_mem_wdata[ 0,8];
264
+ uo.data_in_ready = ~uo.busy;
265
+ $if SIMULATION then
264
266
```
265
267
<!-- MARKDOWN-AUTO-DOCS:END -->
266
268
@@ -280,9 +282,9 @@ We send the next command to the GPU with these two lines:
280
282
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=561-563) -->
281
283
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
282
284
```c
283
- // send next command to GPU
284
- gpu.valid = gpu.ready & ~cmdq.empty ;
285
- cmdq.in_next = gpu.ready & ~cmdq.empty ;
285
+ prev_mem_addr = mem_io_cpu.addr;
286
+ prev_mem_wenable = mem_io_cpu.wenable ;
287
+ prev_mem_wdata = mem_io_cpu.wdata ;
286
288
```
287
289
<!-- MARKDOWN-AUTO-DOCS:END -->
288
290
@@ -293,8 +295,7 @@ itself is given to the GPU through a binding:
293
295
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=336-337) -->
294
296
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
295
297
``` c
296
- // command queue
297
- command_queue cmdq (current :> gpu.command);
298
+ always {
298
299
```
299
300
<!-- MARKDOWN-AUTO-DOCS:END -->
300
301
@@ -304,10 +305,10 @@ initialization. This can be seen in particular in this part of the SOC:
304
305
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=401-404) -->
305
306
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
306
307
```c
307
- // screen interface
308
- screen_ctrl .valid = gpu.screen_valid ;
309
- screen_ctrl .in_data = gpu.screen_valid
310
- ? {1b1,gpu.screen_data} : prev_mem_wdata[0,17] ;
308
+ screen.data_or_command = screen_send_dc;
309
+ screen.byte = screen_send_byte ;
310
+ // uart: maintain low, pulse on send
311
+ uo.data_in_ready = 0 ;
311
312
```
312
313
<!-- MARKDOWN-AUTO-DOCS:END -->
313
314
@@ -317,9 +318,9 @@ or the CPU. The CPU can trigger `screen_ctrl.valid` through a memory mapped addr
317
318
<!-- MARKDOWN-AUTO-DOCS:START (CODE:src=../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si&syntax=c&lines=439-441) -->
318
319
<!-- The below code snippet is automatically added from ../hardware/SOCs/ice40-dmc-1/soc-ice40-dmc-1-risc_v.si -->
319
320
``` c
320
- case 2b01: { // screen write from CPU
321
- screen_ctrl.valid = 1;
322
- }
321
+ oled_resn = ~ prev_mem_wdata[ 0 , 1 ];
322
+ $elseif not MCH2022 then
323
+ o_resn = ~ prev_mem_wdata[ 0 , 1 ];
323
324
```
324
325
<!-- MARKDOWN-AUTO-DOCS:END -->
325
326
0 commit comments