blob: 1899a99f07036fd29edd18955d83886a52bdd45f [file] [log] [blame]
Tim Edwardscd64af52020-08-07 11:11:58 -04001/*
2 * PicoSoC - A simple example SoC using PicoRV32
3 *
4 * Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * Revision 1, July 2019: Added signals to drive flash_clk and flash_csb
19 * output enable (inverted), tied to reset so that the flash is completely
20 * isolated from the processor when the processor is in reset.
21 *
22 * Also: Made ram_wenb a 4-bit bus so that the memory access can be made
23 * byte-wide for byte-wide instructions.
24 */
25
26`ifdef PICORV32_V
27`error "openstriVe_soc.v must be read before picorv32.v!"
28`endif
29
30/* Note: Synthesize register memory from flops */
31/* Inefficient, but not terribly so */
32
33/* Also note: To avoid having a hard macro in the place & route */
34/* (method not finished yet in qflow), SRAM pins are brought out to */
35/* the openstriVe_soc I/O so that openstriVe_soc.v itself is fully synthesizable */
36/* and routable with qflow as-is. */
37
38`define PICORV32_REGS openstriVe_soc_regs
39
40module striVe_soc (
41`ifdef LVS
42 inout vdd1v8, /* 1.8V domain */
43 inout vss,
44`endif
45 input pll_clk,
46 input ext_clk,
47 input ext_clk_sel,
48 /*
49 input ext_reset,
50 input reset,
51 */
52
53 input clk,
54 input resetn,
55 // Main SRAM, including clk and resetn above
56 // (Not used: RAM is synthesized in this version)
57 /*
58 output [3:0] ram_wenb,
59 output [9:0] ram_addr,
60 output [31:0] ram_wdata,
61 input [31:0] ram_rdata,
62 */
63
64 // Memory mapped I/O signals
65 output [15:0] gpio_out_pad, // Connect to out on gpio pad
66 input [15:0] gpio_in_pad, // Connect to in on gpio pad
67 output [15:0] gpio_mode0_pad, // Connect to dm[0] on gpio pad
68 output [15:0] gpio_mode1_pad, // Connect to dm[2] on gpio pad
69 output [15:0] gpio_outenb_pad, // Connect to oe_n on gpio pad
70 output [15:0] gpio_inenb_pad, // Connect to inp_dis on gpio pad
71
72 output adc0_ena,
73 output adc0_convert,
74 input [9:0] adc0_data,
75 input adc0_done,
76 output adc0_clk,
77 output [1:0] adc0_inputsrc,
78 output adc1_ena,
79 output adc1_convert,
80 output adc1_clk,
81 output [1:0] adc1_inputsrc,
82 input [9:0] adc1_data,
83 input adc1_done,
84
85 output dac_ena,
86 output [9:0] dac_value,
87
88 output analog_out_sel, // Analog output select (DAC or bandgap)
89 output opamp_ena, // Op-amp enable for analog output
90 output opamp_bias_ena, // Op-amp bias enable for analog output
91 output bg_ena, // Bandgap enable
92
93 output comp_ena,
94 output [1:0] comp_ninputsrc,
95 output [1:0] comp_pinputsrc,
96 output rcosc_ena,
97
98 output overtemp_ena,
99 input overtemp,
100 input rcosc_in, // RC oscillator output
101 input xtal_in, // crystal oscillator output
102 input comp_in, // comparator output
103 input spi_sck,
104
105 input [7:0] spi_ro_config,
106 input spi_ro_xtal_ena,
107 input spi_ro_reg_ena,
108 input spi_ro_pll_dco_ena,
109 input [4:0] spi_ro_pll_div,
110 input [2:0] spi_ro_pll_sel,
111 input [25:0] spi_ro_pll_trim,
112
113 input [11:0] spi_ro_mfgr_id,
114 input [7:0] spi_ro_prod_id,
115 input [3:0] spi_ro_mask_rev,
116
117 output ser_tx,
118 input ser_rx,
119
120 // IRQ
121 input irq_pin, // dedicated IRQ pin
122 input irq_spi, // IRQ from standalone SPI
123
124 // trap
125 output trap,
126
127 // Flash memory control (SPI master)
128 output flash_csb,
129 output flash_clk,
130
131 output flash_csb_oeb,
132 output flash_clk_oeb,
133
134 output flash_io0_oeb,
135 output flash_io1_oeb,
136 output flash_io2_oeb,
137 output flash_io3_oeb,
138
139 output flash_csb_ieb,
140 output flash_clk_ieb,
141
142 output flash_io0_ieb,
143 output flash_io1_ieb,
144 output flash_io2_ieb,
145 output flash_io3_ieb,
146
147 output flash_io0_do,
148 output flash_io1_do,
149 output flash_io2_do,
150 output flash_io3_do,
151
152 input flash_io0_di,
153 input flash_io1_di,
154 input flash_io2_di,
155 input flash_io3_di
156);
157 /* Increase scratchpad memory to 1K words */
158 /* parameter integer MEM_WORDS = 1024; */
159 /* Memory reverted back to 256 words while memory has to be synthesized */
160 parameter integer MEM_WORDS = 256;
161 parameter [31:0] STACKADDR = (4*MEM_WORDS); // end of memory
162 parameter [31:0] PROGADDR_RESET = 32'h 0010_0000; // 1 MB into flash
163
164// wire resetn;
165// wire clk;
166
167 wire iomem_valid;
168 reg iomem_ready;
169 wire [ 3:0] iomem_wstrb;
170 wire [31:0] iomem_addr;
171 wire [31:0] iomem_wdata;
172 reg [31:0] iomem_rdata;
173
174 // memory-mapped I/O control registers
175
176 wire [15:0] gpio_pullup; // Intermediate GPIO pullup
177 wire [15:0] gpio_pulldown; // Intermediate GPIO pulldown
178 wire [15:0] gpio_outenb; // Intermediate GPIO out enable (bar)
179 wire [15:0] gpio_out; // Intermediate GPIO output
180
181 reg [15:0] gpio; // GPIO output data
182 reg [15:0] gpio_pu; // GPIO pull-up enable
183 reg [15:0] gpio_pd; // GPIO pull-down enable
184 reg [15:0] gpio_oeb; // GPIO output enable (sense negative)
185 reg adc0_ena; // ADC0 enable
186 reg adc0_convert; // ADC0 convert
187 reg [1:0] adc0_clksrc; // ADC0 clock source
188 reg [1:0] adc0_inputsrc; // ADC0 input source
189 reg adc1_ena; // ADC1 enable
190 reg adc1_convert; // ADC1 convert
191 reg [1:0] adc1_clksrc; // ADC1 clock source
192 reg [1:0] adc1_inputsrc; // ADC1 input source
193 reg dac_ena; // DAC enable
194 reg [9:0] dac_value; // DAC output value
195 reg comp_ena; // Comparator enable
196 reg [1:0] comp_ninputsrc; // Comparator negative input source
197 reg [1:0] comp_pinputsrc; // Comparator positive input source
198 reg rcosc_ena; // RC oscillator enable
199 reg overtemp_ena; // Over-temperature alarm enable
200 reg [1:0] comp_output_dest; // Comparator output destination
201 reg [1:0] rcosc_output_dest; // RC oscillator output destination
202 reg [1:0] overtemp_dest; // Over-temperature alarm destination
203 reg [1:0] pll_output_dest; // PLL clock output destination
204 reg [1:0] xtal_output_dest; // Crystal oscillator output destination
205 reg [1:0] trap_output_dest; // Trap signal output destination
206 reg [1:0] irq_7_inputsrc; // IRQ 5 source
207 reg [1:0] irq_8_inputsrc; // IRQ 6 source
208 reg analog_out_sel; // Analog output select
209 reg opamp_ena; // Analog output op-amp enable
210 reg opamp_bias_ena; // Analog output op-amp bias enable
211 reg bg_ena; // Bandgap enable
212 wire adc0_clk; // ADC0 clock (multiplexed)
213 wire adc1_clk; // ADC1 clock (multiplexed)
214
215 wire [3:0] ram_wenb;
216 wire [9:0] ram_addr;
217 wire [31:0] ram_wdata;
218
219// // Clock assignment (to do: make this glitch-free)
220// assign clk = (ext_clk_sel == 1'b1) ? ext_clk : pll_clk;
221//
222// // Reset assignment. "reset" comes from POR, while "ext_reset"
223// // comes from standalone SPI (and is normally zero unless
224// // activated from the SPI).
225//
226// // Staged-delay reset
227// reg [2:0] reset_delay;
228//
229// always @(posedge clk or posedge reset) begin
230// if (reset == 1'b1) begin
231// reset_delay <= 3'b111;
232// end else begin
233// reset_delay <= {1'b0, reset_delay[2:1]};
234// end
235// end
236//
237// assign resetn = ~(reset_delay[0] | ext_reset);
238
239 // ADC clock assignments
240
241 assign adc0_clk = (adc0_clksrc == 2'b00) ? rcosc_in :
242 (adc0_clksrc == 2'b01) ? spi_sck :
243 (adc0_clksrc == 2'b10) ? xtal_in :
244 ext_clk;
245
246 assign adc1_clk = (adc1_clksrc == 2'b00) ? rcosc_in :
247 (adc1_clksrc == 2'b01) ? spi_sck :
248 (adc1_clksrc == 2'b10) ? xtal_in :
249 ext_clk;
250
251 // GPIO assignments
252
253 assign gpio_out[0] = (comp_output_dest == 2'b01) ? comp_in : gpio[0];
254 assign gpio_out[1] = (comp_output_dest == 2'b10) ? comp_in : gpio[1];
255 assign gpio_out[2] = (rcosc_output_dest == 2'b01) ? rcosc_in : gpio[2];
256 assign gpio_out[3] = (rcosc_output_dest == 2'b10) ? rcosc_in : gpio[3];
257 assign gpio_out[4] = (rcosc_output_dest == 2'b11) ? rcosc_in : gpio[4];
258 assign gpio_out[5] = (xtal_output_dest == 2'b01) ? xtal_in : gpio[5];
259 assign gpio_out[6] = (xtal_output_dest == 2'b10) ? xtal_in : gpio[6];
260 assign gpio_out[7] = (xtal_output_dest == 2'b11) ? xtal_in : gpio[7];
261 assign gpio_out[8] = (pll_output_dest == 2'b01) ? pll_clk : gpio[8];
262 assign gpio_out[9] = (pll_output_dest == 2'b10) ? pll_clk : gpio[9];
263 assign gpio_out[10] = (pll_output_dest == 2'b11) ? clk : gpio[10];
264 assign gpio_out[11] = (trap_output_dest == 2'b01) ? trap : gpio[11];
265 assign gpio_out[12] = (trap_output_dest == 2'b10) ? trap : gpio[12];
266 assign gpio_out[13] = (trap_output_dest == 2'b11) ? trap : gpio[13];
267 assign gpio_out[14] = (overtemp_dest == 2'b01) ? overtemp : gpio[14];
268 assign gpio_out[15] = (overtemp_dest == 2'b10) ? overtemp : gpio[15];
269
270 assign gpio_outenb[0] = (comp_output_dest == 2'b00) ? gpio_oeb[0] : 1'b0;
271 assign gpio_outenb[1] = (comp_output_dest == 2'b00) ? gpio_oeb[1] : 1'b0;
272 assign gpio_outenb[2] = (rcosc_output_dest == 2'b00) ? gpio_oeb[2] : 1'b0;
273 assign gpio_outenb[3] = (rcosc_output_dest == 2'b00) ? gpio_oeb[3] : 1'b0;
274 assign gpio_outenb[4] = (rcosc_output_dest == 2'b00) ? gpio_oeb[4] : 1'b0;
275 assign gpio_outenb[5] = (xtal_output_dest == 2'b00) ? gpio_oeb[5] : 1'b0;
276 assign gpio_outenb[6] = (xtal_output_dest == 2'b00) ? gpio_oeb[6] : 1'b0;
277 assign gpio_outenb[7] = (xtal_output_dest == 2'b00) ? gpio_oeb[7] : 1'b0;
278 assign gpio_outenb[8] = (pll_output_dest == 2'b00) ? gpio_oeb[8] : 1'b0;
279 assign gpio_outenb[9] = (pll_output_dest == 2'b00) ? gpio_oeb[9] : 1'b0;
280 assign gpio_outenb[10] = (pll_output_dest == 2'b00) ? gpio_oeb[10] : 1'b0;
281 assign gpio_outenb[11] = (trap_output_dest == 2'b00) ? gpio_oeb[11] : 1'b0;
282 assign gpio_outenb[12] = (trap_output_dest == 2'b00) ? gpio_oeb[12] : 1'b0;
283 assign gpio_outenb[13] = (trap_output_dest == 2'b00) ? gpio_oeb[13] : 1'b0;
284 assign gpio_outenb[14] = (overtemp_dest == 2'b00) ? gpio_oeb[14] : 1'b0;
285 assign gpio_outenb[15] = (overtemp_dest == 2'b00) ? gpio_oeb[15] : 1'b0;
286
287 assign gpio_pullup[0] = (comp_output_dest == 2'b00) ? gpio_pu[0] : 1'b0;
288 assign gpio_pullup[1] = (comp_output_dest == 2'b00) ? gpio_pu[1] : 1'b0;
289 assign gpio_pullup[2] = (rcosc_output_dest == 2'b00) ? gpio_pu[2] : 1'b0;
290 assign gpio_pullup[3] = (rcosc_output_dest == 2'b00) ? gpio_pu[3] : 1'b0;
291 assign gpio_pullup[4] = (rcosc_output_dest == 2'b00) ? gpio_pu[4] : 1'b0;
292 assign gpio_pullup[5] = (xtal_output_dest == 2'b00) ? gpio_pu[5] : 1'b0;
293 assign gpio_pullup[6] = (xtal_output_dest == 2'b00) ? gpio_pu[6] : 1'b0;
294 assign gpio_pullup[7] = (xtal_output_dest == 2'b00) ? gpio_pu[7] : 1'b0;
295 assign gpio_pullup[8] = (pll_output_dest == 2'b00) ? gpio_pu[8] : 1'b0;
296 assign gpio_pullup[9] = (pll_output_dest == 2'b00) ? gpio_pu[9] : 1'b0;
297 assign gpio_pullup[10] = (pll_output_dest == 2'b00) ? gpio_pu[10] : 1'b0;
298 assign gpio_pullup[11] = (trap_output_dest == 2'b00) ? gpio_pu[11] : 1'b0;
299 assign gpio_pullup[12] = (trap_output_dest == 2'b00) ? gpio_pu[12] : 1'b0;
300 assign gpio_pullup[13] = (trap_output_dest == 2'b00) ? gpio_pu[13] : 1'b0;
301 assign gpio_pullup[14] = (overtemp_dest == 2'b00) ? gpio_pu[14] : 1'b0;
302 assign gpio_pullup[15] = (overtemp_dest == 2'b00) ? gpio_pu[15] : 1'b0;
303
304 assign gpio_pulldown[0] = (comp_output_dest == 2'b00) ? gpio_pd[0] : 1'b0;
305 assign gpio_pulldown[1] = (comp_output_dest == 2'b00) ? gpio_pd[1] : 1'b0;
306 assign gpio_pulldown[2] = (rcosc_output_dest == 2'b00) ? gpio_pd[2] : 1'b0;
307 assign gpio_pulldown[3] = (rcosc_output_dest == 2'b00) ? gpio_pd[3] : 1'b0;
308 assign gpio_pulldown[4] = (rcosc_output_dest == 2'b00) ? gpio_pd[4] : 1'b0;
309 assign gpio_pulldown[5] = (xtal_output_dest == 2'b00) ? gpio_pd[5] : 1'b0;
310 assign gpio_pulldown[6] = (xtal_output_dest == 2'b00) ? gpio_pd[6] : 1'b0;
311 assign gpio_pulldown[7] = (xtal_output_dest == 2'b00) ? gpio_pd[7] : 1'b0;
312 assign gpio_pulldown[8] = (pll_output_dest == 2'b00) ? gpio_pd[8] : 1'b0;
313 assign gpio_pulldown[9] = (pll_output_dest == 2'b00) ? gpio_pd[9] : 1'b0;
314 assign gpio_pulldown[10] = (pll_output_dest == 2'b00) ? gpio_pd[10] : 1'b0;
315 assign gpio_pulldown[11] = (trap_output_dest == 2'b00) ? gpio_pd[11] : 1'b0;
316 assign gpio_pulldown[12] = (trap_output_dest == 2'b00) ? gpio_pd[12] : 1'b0;
317 assign gpio_pulldown[13] = (trap_output_dest == 2'b00) ? gpio_pd[13] : 1'b0;
318 assign gpio_pulldown[14] = (overtemp_dest == 2'b00) ? gpio_pd[14] : 1'b0;
319 assign gpio_pulldown[15] = (overtemp_dest == 2'b00) ? gpio_pd[15] : 1'b0;
320
321 // Convert GPIO signals to s8 pad signals
322 convert_gpio_sigs convert_gpio_bit [15:0] (
323 .gpio_out(gpio_out),
324 .gpio_outenb(gpio_outenb),
325 .gpio_pu(gpio_pullup),
326 .gpio_pd(gpio_pulldown),
327 .gpio_out_pad(gpio_out_pad),
328 .gpio_outenb_pad(gpio_outenb_pad),
329 .gpio_inenb_pad(gpio_inenb_pad),
330 .gpio_mode1_pad(gpio_mode1_pad),
331 .gpio_mode0_pad(gpio_mode0_pad)
332 );
333
334 wire irq_7, irq_8;
335
336 assign irq_7 = (irq_7_inputsrc == 2'b01) ? gpio_in_pad[0] :
337 (irq_7_inputsrc == 2'b10) ? gpio_in_pad[1] :
338 (irq_7_inputsrc == 2'b11) ? gpio_in_pad[2] : 1'b0;
339 assign irq_8 = (irq_8_inputsrc == 2'b01) ? gpio_in_pad[3] :
340 (irq_8_inputsrc == 2'b10) ? gpio_in_pad[4] :
341 (irq_8_inputsrc == 2'b11) ? gpio_in_pad[5] : 1'b0;
342
343 assign ram_wenb = (mem_valid && !mem_ready && mem_addr < 4*MEM_WORDS) ?
344 {~mem_wstrb[3], ~mem_wstrb[2], ~mem_wstrb[1], ~mem_wstrb[0]} : 4'b1111;
345 assign ram_addr = mem_addr[11:2];
346 assign ram_wdata = mem_wdata; // Just for naming conventions.
347
348 reg [31:0] irq;
349 wire irq_stall = 0;
350 wire irq_uart = 0;
351
352 always @* begin
353 irq = 0;
354 irq[3] = irq_stall;
355 irq[4] = irq_uart;
356 irq[5] = irq_pin;
357 irq[6] = irq_spi;
358 irq[7] = irq_7;
359 irq[8] = irq_8;
360 irq[9] = comp_output_dest[0] & comp_output_dest[1] & comp_in;
361 irq[10] = overtemp_dest[0] & overtemp_dest[1] & overtemp;
362 end
363
364 wire mem_valid;
365 wire mem_instr;
366 wire mem_ready;
367 wire [31:0] mem_addr;
368 wire [31:0] mem_wdata;
369 wire [3:0] mem_wstrb;
370 wire [31:0] mem_rdata;
371
372 wire spimem_ready;
373 wire [31:0] spimem_rdata;
374
375 reg ram_ready;
376 wire [31:0] ram_rdata;
377
378 assign iomem_valid = mem_valid && (mem_addr[31:24] > 8'h 01);
379 assign iomem_wstrb = mem_wstrb;
380 assign iomem_addr = mem_addr;
381 assign iomem_wdata = mem_wdata;
382
383 wire spimemio_cfgreg_sel = mem_valid && (mem_addr == 32'h 0200_0000);
384 wire [31:0] spimemio_cfgreg_do;
385
386 wire simpleuart_reg_div_sel = mem_valid && (mem_addr == 32'h 0200_0004);
387 wire [31:0] simpleuart_reg_div_do;
388
389 wire simpleuart_reg_dat_sel = mem_valid && (mem_addr == 32'h 0200_0008);
390 wire [31:0] simpleuart_reg_dat_do;
391 wire simpleuart_reg_dat_wait;
392
393 assign mem_ready = (iomem_valid && iomem_ready) || spimem_ready || ram_ready || spimemio_cfgreg_sel ||
394 simpleuart_reg_div_sel || (simpleuart_reg_dat_sel && !simpleuart_reg_dat_wait);
395
396 assign mem_rdata = (iomem_valid && iomem_ready) ? iomem_rdata : spimem_ready ? spimem_rdata : ram_ready ? ram_rdata :
397 spimemio_cfgreg_sel ? spimemio_cfgreg_do : simpleuart_reg_div_sel ? simpleuart_reg_div_do :
398 simpleuart_reg_dat_sel ? simpleuart_reg_dat_do : 32'h 0000_0000;
399
400 picorv32 #(
401 .STACKADDR(STACKADDR),
402 .PROGADDR_RESET(PROGADDR_RESET),
403 .PROGADDR_IRQ(32'h 0000_0000),
404 .BARREL_SHIFTER(1),
405 .COMPRESSED_ISA(1),
406 .ENABLE_MUL(1),
407 .ENABLE_DIV(1),
408 .ENABLE_IRQ(1),
409 .ENABLE_IRQ_QREGS(0)
410 ) cpu (
411 .clk (clk ),
412 .resetn (resetn ),
413 .mem_valid (mem_valid ),
414 .mem_instr (mem_instr ),
415 .mem_ready (mem_ready ),
416 .mem_addr (mem_addr ),
417 .mem_wdata (mem_wdata ),
418 .mem_wstrb (mem_wstrb ),
419 .mem_rdata (mem_rdata ),
420 .irq (irq ),
421 .trap (trap )
422 );
423
424 spimemio spimemio (
425 .clk (clk),
426 .resetn (resetn),
427 .valid (mem_valid && mem_addr >= 4*MEM_WORDS && mem_addr < 32'h 0200_0000),
428 .ready (spimem_ready),
429 .addr (mem_addr[23:0]),
430 .rdata (spimem_rdata),
431
432 .flash_csb (flash_csb ),
433 .flash_clk (flash_clk ),
434
435 .flash_csb_oeb (flash_csb_oeb),
436 .flash_clk_oeb (flash_clk_oeb),
437
438 .flash_io0_oeb (flash_io0_oeb),
439 .flash_io1_oeb (flash_io1_oeb),
440 .flash_io2_oeb (flash_io2_oeb),
441 .flash_io3_oeb (flash_io3_oeb),
442
443 .flash_csb_ieb (flash_csb_ieb),
444 .flash_clk_ieb (flash_clk_ieb),
445
446 .flash_io0_ieb (flash_io0_ieb),
447 .flash_io1_ieb (flash_io1_ieb),
448 .flash_io2_ieb (flash_io2_ieb),
449 .flash_io3_ieb (flash_io3_ieb),
450
451 .flash_io0_do (flash_io0_do),
452 .flash_io1_do (flash_io1_do),
453 .flash_io2_do (flash_io2_do),
454 .flash_io3_do (flash_io3_do),
455
456 .flash_io0_di (flash_io0_di),
457 .flash_io1_di (flash_io1_di),
458 .flash_io2_di (flash_io2_di),
459 .flash_io3_di (flash_io3_di),
460
461 .cfgreg_we(spimemio_cfgreg_sel ? mem_wstrb : 4'b 0000),
462 .cfgreg_di(mem_wdata),
463 .cfgreg_do(spimemio_cfgreg_do)
464 );
465
466 simpleuart simpleuart (
467 .clk (clk ),
468 .resetn (resetn ),
469
470 .ser_tx (ser_tx ),
471 .ser_rx (ser_rx ),
472
473 .reg_div_we (simpleuart_reg_div_sel ? mem_wstrb : 4'b 0000),
474 .reg_div_di (mem_wdata),
475 .reg_div_do (simpleuart_reg_div_do),
476
477 .reg_dat_we (simpleuart_reg_dat_sel ? mem_wstrb[0] : 1'b 0),
478 .reg_dat_re (simpleuart_reg_dat_sel && !mem_wstrb),
479 .reg_dat_di (mem_wdata),
480 .reg_dat_do (simpleuart_reg_dat_do),
481 .reg_dat_wait(simpleuart_reg_dat_wait)
482 );
483
484 always @(posedge clk)
485 ram_ready <= mem_valid && !mem_ready && mem_addr < 4*MEM_WORDS;
486
487 // PicoSoC memory mapped IP
488 // 2 ADCs (1 multiplexed from internal signals, including core 1.8V VDD,
489 // DAC output, comparator input, external input)
490 // 1 DAC
491 // 1 comparator (1 end tied to DAC, other could be shared w/ADC input)
492 // 1 RC oscillator (output can be tied to one or both ADC clocks)
493 // 1 crystal oscillator (output to level-shift-down = 3V buffer powered at 1.8V)
494 // 1 1.8V regulator (sets VDD on padframe)
495 // 1 bandgap
496 // 1 power-on-reset (POR)
497 // 1 temperature alarm
498
499 // NOTE: Signals affecting critical core functions are controlled through
500 // an independent SPI having read-only access through the picorv32 core.
501 // SPI pins are independent of picorv32 SPI master. Signals controlled by
502 // the SPI are:
503 // 1) crystal oscillator enable (default on)
504 // 2) 1.8V regulator enable (default on)
505 // 3) bandgap enable (default on)
506 // 4) picorv32 internal debug signals (TBD)
507 // 5) additional picorv32 IRQ (TBD)
508 // 6) PLL enables (default on)
509 // 7) PLL trim (default TBD)
510 // NOTE: SPI should have a pass-through mode that configures SDO as a
511 // copy of a chosen signal for as long as CSB is held low. This can be
512 // an SPI command, allows other internal signals to be passed to the
513 // output and viewed, including the RC oscillator output, comparator output,
514 // and other edge-based signals.
515
516 // Memory map:
517 // NOTE:
518
519 // SPI master: 0x02000000 (control)
520 // UART: 0x02000004-8 (clock, data)
521 // GPIO: 0x03000000 (in/out, pu/pd, data)
522 // ADC0: 0x03000020
523 // ADC1: 0x03000040
524 // DAC: 0x03000060
525 // comparator: 0x03000080
526 // RC osc: 0x030000a0
527 // SPI slave: 0x030000c0 (read-only)
528
529 // Memory map details:
530 // GPIO: 32 channels total.
531 // addr 0x03000000 data (16 bits)
532 // addr 0x03000001 out (=1) or in (=0) (default 0)
533 // addr 0x03000002 pu (=1) or none (=0) (default 0)
534 // addr 0x03000003 pd (=1) or none (=0) (default 0)
535 // addr 0x03000004-f reserved (may be used for other pad I/O)
536 //
537 // ADC0: addr 0x03000020 enable
538 // addr 0x03000021 data (read-only)
539 // addr 0x03000022 done (read-only)
540 // addr 0x03000023 start conversion
541 // addr 0x03000024 clock source (RC osc, SPI clk, xtal, core)
542 // addr 0x03000025 input source (core VDD, ext, DAC, comp in)
543 //
544 // ADC1: addr 0x03000040 enable
545 // addr 0x03000041 data (read-only)
546 // addr 0x03000042 done (read-only)
547 // addr 0x03000043 start conversion
548 // addr 0x03000044 clock source (RC osc, SPI clk, xtal, core)
549 // addr 0x03000045 input source (bg, ext, I/O vdd, gnd)
550 //
551 // DAC: addr 0x03000060 enable
552 // addr 0x03000061 value
553 //
554 // comparator: addr 0x03000080 enable
555 // addr 0x03000081 value
556 // addr 0x03000082 input source (DAC, bg, core VDD, ext)
557 // addr 0x03000083 output dest (ext gpio pin 0-1, IRQ, none)
558 //
559 // bandgap: addr 0x03000090 enable
560 //
561 // RC osc: addr 0x030000a0 enable
562 // addr 0x030000a1 output dest (ext gpio pin 2-4)
563 //
564 // SPI slave: addr 0x030000c0 SPI configuration
565 // addr 0x030000c1 xtal osc, reg, bg enables
566 // addr 0x030000c2 PLL enables, trim
567 // addr 0x030000c3 manufacturer ID
568 // addr 0x030000c4 product ID
569 // addr 0x030000c5 product mask revision
570 // Xtal mon: addr 0x030000c6 xtal osc output dest (ext gpio pin 5-7)
571 // PLL mon: addr 0x030000c7 PLL output dest (ext gpio pin 8-10)
572 // trap mon: addr 0x030000c8 trap output dest (ext gpio pin 11-13)
573 // IRQ7 src: addr 0x030000c9 IRQ 7 source (ext gpio pin 0-3)
574 // IRQ8 src: addr 0x030000ca IRQ 8 source (ext gpio pin 4-7)
575 // Analog: addr 0x030000cb analog output select (DAC, bg)
576 //
577 // Overtemp: addr 0x030000e0 over-temperature alarm enable
578 // addr 0x030000e1 over-temperature alarm data
579 // addr 0x030000e2 output dest (ext gpio pin 14-15, IRQ)
580
581 always @(posedge clk) begin
582 if (!resetn) begin
583 gpio <= 0;
584 gpio_oeb <= 16'hffff;
585 gpio_pu <= 0;
586 gpio_pd <= 0;
587 adc0_ena <= 0;
588 adc0_convert <= 0;
589 adc0_clksrc <= 0;
590 adc0_inputsrc <= 0;
591 adc1_ena <= 0;
592 adc1_convert <= 0;
593 adc1_clksrc <= 0;
594 adc1_inputsrc <= 0;
595 dac_ena <= 0;
596 dac_value <= 0;
597 comp_ena <= 0;
598 comp_ninputsrc <= 0;
599 comp_pinputsrc <= 0;
600 rcosc_ena <= 0;
601 comp_output_dest <= 0;
602 rcosc_output_dest <= 0;
603 overtemp_dest <= 0;
604 overtemp_ena <= 0;
605 pll_output_dest <= 0;
606 xtal_output_dest <= 0;
607 trap_output_dest <= 0;
608 irq_7_inputsrc <= 0;
609 irq_8_inputsrc <= 0;
610 analog_out_sel <= 0;
611 opamp_ena <= 0;
612 opamp_bias_ena <= 0;
613 bg_ena <= 0;
614
615 end else begin
616 iomem_ready <= 0;
617 if (iomem_valid && !iomem_ready && iomem_addr[31:8] == 24'h030000) begin
618 iomem_ready <= 1;
619 if (iomem_addr[7:0] == 8'h00) begin
620 iomem_rdata <= {gpio_out, gpio_in_pad};
621 if (iomem_wstrb[0]) gpio[ 7: 0] <= iomem_wdata[ 7: 0];
622 if (iomem_wstrb[1]) gpio[15: 8] <= iomem_wdata[15: 8];
623 end else if (iomem_addr[7:0] == 8'h04) begin
624 iomem_rdata <= {16'd0, gpio_oeb};
625 if (iomem_wstrb[0]) gpio_oeb[ 7: 0] <= iomem_wdata[ 7: 0];
626 if (iomem_wstrb[1]) gpio_oeb[15: 8] <= iomem_wdata[15: 8];
627 end else if (iomem_addr[7:0] == 8'h08) begin
628 iomem_rdata <= {16'd0, gpio_pu};
629 if (iomem_wstrb[0]) gpio_pu[ 7: 0] <= iomem_wdata[ 7: 0];
630 if (iomem_wstrb[1]) gpio_pu[15: 8] <= iomem_wdata[15: 8];
631 end else if (iomem_addr[7:0] == 8'h0c) begin
632 iomem_rdata <= {16'd0, gpio_pu};
633 if (iomem_wstrb[0]) gpio_pd[ 7: 0] <= iomem_wdata[ 7: 0];
634 if (iomem_wstrb[1]) gpio_pd[15: 8] <= iomem_wdata[15: 8];
635 end else if (iomem_addr[7:0] == 8'h10) begin
636 iomem_rdata <= {31'd0, adc0_ena};
637 if (iomem_wstrb[0]) adc0_ena <= iomem_wdata[0];
638 end else if (iomem_addr[7:0] == 8'h14) begin
639 iomem_rdata <= {22'd0, adc0_data};
640 end else if (iomem_addr[7:0] == 8'h18) begin
641 iomem_rdata <= {31'd0, adc0_done};
642 end else if (iomem_addr[7:0] == 8'h1c) begin
643 iomem_rdata <= {31'd0, adc0_convert};
644 if (iomem_wstrb[0]) adc0_convert <= iomem_wdata[0];
645 end else if (iomem_addr[7:0] == 8'h20) begin
646 iomem_rdata <= {30'd0, adc0_clksrc};
647 if (iomem_wstrb[0]) adc0_clksrc <= iomem_wdata[1:0];
648 end else if (iomem_addr[7:0] == 8'h24) begin
649 iomem_rdata <= {30'd0, adc0_inputsrc};
650 if (iomem_wstrb[0]) adc0_inputsrc <= iomem_wdata[1:0];
651 end else if (iomem_addr[7:0] == 8'h30) begin
652 iomem_rdata <= {31'd0, adc1_ena};
653 if (iomem_wstrb[0]) adc1_ena <= iomem_wdata[0];
654 end else if (iomem_addr[7:0] == 8'h34) begin
655 iomem_rdata <= {22'd0, adc1_data};
656 end else if (iomem_addr[7:0] == 8'h38) begin
657 iomem_rdata <= {31'd0, adc1_done};
658 end else if (iomem_addr[7:0] == 8'h3c) begin
659 iomem_rdata <= {31'd0, adc1_convert};
660 if (iomem_wstrb[0]) adc1_convert <= iomem_wdata[0];
661 end else if (iomem_addr[7:0] == 8'h40) begin
662 iomem_rdata <= {30'd0, adc1_clksrc};
663 if (iomem_wstrb[0]) adc1_clksrc <= iomem_wdata[1:0];
664 end else if (iomem_addr[7:0] == 8'h44) begin
665 iomem_rdata <= {30'd0, adc1_inputsrc};
666 if (iomem_wstrb[0]) adc1_inputsrc <= iomem_wdata[1:0];
667 end else if (iomem_addr[7:0] == 8'h50) begin
668 iomem_rdata <= {31'd0, dac_ena};
669 if (iomem_wstrb[0]) dac_ena <= iomem_wdata[0];
670 end else if (iomem_addr[7:0] == 8'h54) begin
671 iomem_rdata <= {22'd0, dac_value};
672 if (iomem_wstrb[0]) dac_value[7:0] <= iomem_wdata[7:0];
673 if (iomem_wstrb[1]) dac_value[9:8] <= iomem_wdata[9:8];
674 end else if (iomem_addr[7:0] == 8'h60) begin
675 iomem_rdata <= {31'd0, comp_ena};
676 if (iomem_wstrb[0]) comp_ena <= iomem_wdata[0];
677 end else if (iomem_addr[7:0] == 8'h64) begin
678 iomem_rdata <= {30'd0, comp_ninputsrc};
679 if (iomem_wstrb[0]) comp_ninputsrc <= iomem_wdata[1:0];
680 end else if (iomem_addr[7:0] == 8'h68) begin
681 iomem_rdata <= {30'd0, comp_pinputsrc};
682 if (iomem_wstrb[0]) comp_pinputsrc <= iomem_wdata[1:0];
683 end else if (iomem_addr[7:0] == 8'h6c) begin
684 iomem_rdata <= {30'd0, comp_output_dest};
685 if (iomem_wstrb[0]) comp_output_dest <= iomem_wdata[1:0];
686 end else if (iomem_addr[7:0] == 8'h70) begin
687 iomem_rdata <= {31'd0, rcosc_ena};
688 if (iomem_wstrb[0]) rcosc_ena <= iomem_wdata[0];
689 end else if (iomem_addr[7:0] == 8'h74) begin
690 iomem_rdata <= {30'd0, rcosc_output_dest};
691 if (iomem_wstrb[0]) rcosc_output_dest <= iomem_wdata[1:0];
692 end else if (iomem_addr[7:0] == 8'h80) begin
693 iomem_rdata <= {24'd0, spi_ro_config};
694 end else if (iomem_addr[7:0] == 8'h84) begin
695 iomem_rdata <= {22'd0, spi_ro_pll_div, spi_ro_pll_sel, spi_ro_xtal_ena, spi_ro_reg_ena};
696 end else if (iomem_addr[7:0] == 8'h88) begin
697 iomem_rdata <= {5'd0, spi_ro_pll_trim, spi_ro_pll_dco_ena};
698 end else if (iomem_addr[7:0] == 8'h8c) begin
699 iomem_rdata <= {20'd0, spi_ro_mfgr_id};
700 end else if (iomem_addr[7:0] == 8'h90) begin
701 iomem_rdata <= {24'd0, spi_ro_prod_id};
702 end else if (iomem_addr[7:0] == 8'h94) begin
703 iomem_rdata <= {28'd0, spi_ro_mask_rev};
704 end else if (iomem_addr[7:0] == 8'h98) begin
705 iomem_rdata <= {31'd0, ext_clk_sel};
706 end else if (iomem_addr[7:0] == 8'ha0) begin
707 iomem_rdata <= {30'd0, xtal_output_dest};
708 if (iomem_wstrb[0]) xtal_output_dest <= iomem_wdata[1:0];
709 end else if (iomem_addr[7:0] == 8'ha4) begin
710 iomem_rdata <= {30'd0, pll_output_dest};
711 if (iomem_wstrb[0]) pll_output_dest <= iomem_wdata[1:0];
712 end else if (iomem_addr[7:0] == 8'ha8) begin
713 iomem_rdata <= {30'd0, trap_output_dest};
714 if (iomem_wstrb[0]) trap_output_dest <= iomem_wdata[1:0];
715 end else if (iomem_addr[7:0] == 8'hb0) begin
716 iomem_rdata <= {30'd0, irq_7_inputsrc};
717 if (iomem_wstrb[0]) irq_7_inputsrc <= iomem_wdata[1:0];
718 end else if (iomem_addr[7:0] == 8'hb4) begin
719 iomem_rdata <= {30'd0, irq_8_inputsrc};
720 if (iomem_wstrb[0]) irq_8_inputsrc <= iomem_wdata[1:0];
721 end else if (iomem_addr[7:0] == 8'hc0) begin
722 iomem_rdata <= {31'd0, analog_out_sel};
723 if (iomem_wstrb[0]) analog_out_sel <= iomem_wdata[0];
724 end else if (iomem_addr[7:0] == 8'hc4) begin
725 iomem_rdata <= {31'd0, opamp_bias_ena};
726 if (iomem_wstrb[0]) opamp_bias_ena <= iomem_wdata[0];
727 end else if (iomem_addr[7:0] == 8'hc8) begin
728 iomem_rdata <= {31'd0, opamp_ena};
729 if (iomem_wstrb[0]) opamp_ena <= iomem_wdata[0];
730 end else if (iomem_addr[7:0] == 8'hd0) begin
731 iomem_rdata <= {31'd0, bg_ena};
732 if (iomem_wstrb[0]) bg_ena <= iomem_wdata[0];
733 end else if (iomem_addr[7:0] == 8'he0) begin
734 iomem_rdata <= {31'd0, overtemp_ena};
735 if (iomem_wstrb[0]) overtemp_ena <= iomem_wdata[0];
736 end else if (iomem_addr[7:0] == 8'he4) begin
737 iomem_rdata <= {31'd0, overtemp};
738 end else if (iomem_addr[7:0] == 8'he8) begin
739 iomem_rdata <= {30'd0, overtemp_dest};
740 if (iomem_wstrb[0]) overtemp_dest <= iomem_wdata[1:0];
741 end
742 end
743 end
744 end
745
746 openstriVe_soc_mem #(.WORDS(MEM_WORDS)) picomem (
747 .clk(clk),
748 .ena(resetn),
749 .wen((mem_valid && !mem_ready && mem_addr < 4*MEM_WORDS) ? mem_wstrb : 4'b0),
750 .addr(mem_addr[23:2]),
751 .wdata(mem_wdata),
752 .rdata(ram_rdata)
753 );
754endmodule
755
756`include "picorv32.v"
757`include "spimemio.v"
758`include "simpleuart.v"
759
760// Implementation note:
761// Replace the following two modules with wrappers for your SRAM cells.
762
763module openstriVe_soc_regs (
764 input clk, wen,
765 input [5:0] waddr,
766 input [5:0] raddr1,
767 input [5:0] raddr2,
768 input [31:0] wdata,
769 output [31:0] rdata1,
770 output [31:0] rdata2
771);
772 reg [31:0] regs [0:31];
773
774 always @(posedge clk)
775 if (wen) regs[waddr[4:0]] <= wdata;
776
777 assign rdata1 = regs[raddr1[4:0]];
778 assign rdata2 = regs[raddr2[4:0]];
779endmodule
780
781module openstriVe_soc_mem #(
782 parameter integer WORDS = 256
783) (
784 input clk,
785 input ena,
786 input [3:0] wen,
787 input [21:0] addr,
788 input [31:0] wdata,
789 output reg [31:0] rdata
790);
791 reg [31:0] mem [0:WORDS-1];
792
793 always @(posedge clk) begin
794 if (ena == 1'b1) begin
795 rdata <= mem[addr];
796 if (wen[0]) mem[addr][ 7: 0] <= wdata[ 7: 0];
797 if (wen[1]) mem[addr][15: 8] <= wdata[15: 8];
798 if (wen[2]) mem[addr][23:16] <= wdata[23:16];
799 if (wen[3]) mem[addr][31:24] <= wdata[31:24];
800 end
801 end
802endmodule
803
804/* Convert the standard set of GPIO signals: input, output, output_enb,
805 * pullup, and pulldown into the set needed by the s8 GPIO pads:
806 * input, output, output_enb, input_enb, mode. Note that dm[2] on
807 * thepads is always equal to dm[1] in this setup, so mode is shown as
808 * only a 2-bit signal.
809 *
810 * This module is bit-sliced. Instantiate once for each GPIO pad.
811 */
812
813module convert_gpio_sigs (
814 input gpio_out,
815 input gpio_outenb,
816 input gpio_pu,
817 input gpio_pd,
818 output gpio_out_pad,
819 output gpio_outenb_pad,
820 output gpio_inenb_pad,
821 output gpio_mode1_pad,
822 output gpio_mode0_pad
823);
824
825 assign gpio_out_pad = (gpio_pu == 1'b0 && gpio_pd == 1'b0) ? gpio_out :
826 (gpio_pu == 1'b1) ? 1 : 0;
827
828 assign gpio_outenb_pad = (gpio_outenb == 1'b0) ? 0 :
829 (gpio_pu == 1'b1 || gpio_pd == 1'b1) ? 0 : 1;
830
831 assign gpio_inenb_pad = ~gpio_outenb;
832
833 assign gpio_mode1_pad = ~gpio_outenb_pad;
834 assign gpio_mode0_pad = gpio_outenb;
835
836endmodule
837