/
openxlr8.v
executable file
·419 lines (370 loc) · 16.5 KB
/
openxlr8.v
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
///////////////////////////////////////////////////////////////////
//=================================================================
// Copyright (c) Alorium Technology 2016
// ALL RIGHTS RESERVED
// $Id: $
//=================================================================
//
// File name: : openxlr8.v
// Author : Steve Phillips
// Description : Wrapper module to hold instantiations of
// OpenXLR8 XB modules.
//
// This module is edited by the OpenXLR8 user to instantiate their
// XB(s) into the design. This module provides the input, output and
// control signals needed to connect the XB(s) into the logic in the
// top verilog module. Some wiring is required beyond simply
// instantiating the XB, especially in the case of multiple XBs, but
// the comments included here should explain what is needed.
//
// This file is organized in to several sections with helpful
// comments in each. The sections are:
//
// 1.) Parameters
// NUM_PINS should not be edited, but NUM_OXBS should be set
// to the number of XBs being instantiated in this file.
// 2.) Inputs and Outputs
// No changes should be needed here. The inputs and outputs
// are defined.
// 3.) Regs and Wires
// This section starts with some required wire definitions
// and then provides hints for addition regs and wires that
// may be needed, You'll going to need to add at least a
// few lines here.
// 4.) Instantiate XBs
// This is where all the XBs should be specified by instantiating
// the XB module and setting the xbs_* signals for that XB. The
// basic template should be repeated for each XB being used. Don't
// forget to set the NUM_OXBS value back in section 1 to match the
// number of XBs!
// 5.) Combining logic
// This section begins with some logic to cobine the xbs_* signals
// into the xb_* signals needed for the outputs. Then there are
// some hints and examples for how to write the logic to combine
// the dbusout and out_en signals from the XBs.
// 6.) Interrupt logic
// This section instantiates the xlr8_pcint.v module if there are
// interrupts needed for the OpenXLR8 implementation. The OpenXLR8
// module has a single IRQ output that ties into the AVR interrupt
// handler.
//
//=================================================================
///////////////////////////////////////////////////////////////////
`include "xb_adr_pack.vh"
module openxlr8
//======================================================================
// Normally the instantiation parameters and module I/O would be
// listed inline here. To make the module more easily updated, that
// code has been moved to an include file located in the XLR8Core. It
// is inserted here at compile time.
`include "../../../XLR8Core/extras/rtl/openxlr8_module_io.vh"
// Listed below is the instantiation parameters and module I/O of
// the current version. It is listed only to provide an example of
// what they should be. To see the actual code, see the file
// included above.
/* === Beginning of Sample Instantiation Parameters and Module I/O ===
// ----------------------------------------------------------------------
// 1.) Parameters
#(
parameter DESIGN_CONFIG = 8,
// {
// 25'd0, // [31:14] - reserved
// 8'h8, // [13:6] - MAX10 Size, ex: 0x8 = M08, 0x32 = M50
// 1'b0, // [5] - ADC_SWIZZLE, 0 = XLR8, 1 = Sno
// 1'b0, // [4] - PLL Speed, 0 = 16MHz PLL, 1 = 50Mhz PLL
// 1'b1, // [3] - PMEM Size, 0 = 8K (Sim Kludge), 1 = 16K
// 2'd0, // [2:1] - Clock Speed, 0 = 16MHZ, 1 = 32MHz, 2 = 64MHz, 3=na
// 1'b0 // [0] - FPGA Image, 0 = CFM Application, 1 = CFM Factory
// },
parameter NUM_PINS = 20,// Default is Arduino Uno Digital 0-13 + Analog 0-5
// NUM_PINS should be 20 for the XLR8 board, ?? for the Sno board
parameter OX8ICR_Address = 8'h31,
parameter OX8IFR_Address = 8'h32,
parameter OX8MSK_Address = 8'h33
// The OX8*_Address parameters are used to control the interrupt module
)
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// 2.) Inputs and Outputs
(
// Clock and Reset
// The clk input is the CPU core frequency, which could be 16, 32 or 64MHZ
// depending on how the image was built
input clk, // Clock
input rstn, // Reset
// These three clocks are always the stated frequency, regardless of the CPU
// core frequency
input clk_64mhz, // 64MHz clock
input clk_32mhz, // 32MHz clock
input clk_16mhz, // 16MHz clock
input clk_option2, // Default: 64MHz, 45 degrees phase
input clk_option4, // Default: 32MHz, 22.5 degrees phase
// These enables have one shot pulses at the stated intrevals
input en16mhz, // Enable for 16MHz timer
input en1mhz, // Enable for 1MHz timer
input en128khz, // Enable for 128KHz timer
// I/O
input [5:0] adr, // Reg Address
input [7:0] dbus_in, // Data Bus Input
output [7:0] dbus_out, // Data Bus Output
output io_out_en, // IO Output Enable
input iore, // IO Reade Enable
input iowe, // IO Write Enable
// DM
input [7:0] ramadr, // RAM Address
input ramre, // RAM Read Enable
input ramwe, // RAM Write Enable
input dm_sel, // DM Select
input [7:0] dm_dout_rg,// dout held during cpuwait, for UART
// Other
input [255:0] gprf, // Direct RO access to Reg File
input [NUM_PINS-1:0] xb_pinx, // pin inputs
inout JT9, // JTAG pin
inout JT7, // JTAG pin
inout JT6, // JTAG pin
inout JT5, // JTAG pin
inout JT3, // JTAG pin
inout JT1, // JTAG pin
// For iomux
output logic [NUM_PINS-1:0] xb_ddoe, // override data direction
output logic [NUM_PINS-1:0] xb_ddov, // data direction value if
// overridden (1=output)
output logic [NUM_PINS-1:0] xb_pvoe, // override output value
output logic [NUM_PINS-1:0] xb_pvov, // output value if overridden
// Interrupts
output logic xb_irq // To core
);
//----------------------------------------------------------------------
=== End of Sample Instantiation Parameters and Module I/O === */
//----------------------------------------------------------------------
// 3.) Params, Regs and Wires declarations
//
parameter NUM_OXBS = 1; // !! EDIT THIS LINE !!
// NUM_OXBS should equal the number of XBs being instantiated within
// this module. However, in the case where no XB is being
// instantiated, the value should be set to 1 rather than zero, so
// that the logic compiles correctly and we can still provide the
// correct output values. Called it NUM_OXBS for OpenXLR8 XBs, to
// differentiate is from the NUM_XBS parameter used in the top.
// These are required:
logic [NUM_OXBS-1:0][NUM_PINS-1:0] xbs_ddoe;
logic [NUM_OXBS-1:0][NUM_PINS-1:0] xbs_ddov;
logic [NUM_OXBS-1:0][NUM_PINS-1:0] xbs_pvoe;
logic [NUM_OXBS-1:0][NUM_PINS-1:0] xbs_pvov;
// Add additional wires and regs here as needed to connect your XBs
// to the combining logic and to each other if needed. At minimum,
// with a single XB, you'll need at least something like this:
logic [7:0] spi_dbusout;
logic spi_io_out_en;
logic misoo, mosio;
logic scko;
logic spe;
logic spimaster;
logic ss_b;
logic sckiii; // FIXME: This is a hack, should probably remove
// the scki input to this module and
// make this the real scki
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// 4.) Instantiate XBs
//----------------------------------------------------------------------
// Instantiate XB module and configure control signals
//
assign sckiii = xb_pinx[7];
assign misoi = xb_pinx[6];
assign mosii = xb_pinx[5];
assign ss_b = xb_pinx[4];
avr_spi
xlr8_spi_inst
(
// AVR Control
.adr (adr),
.dbus_in (dbus_in),
.dbus_out (spi_dbusout),
.iore (iore),
.iowe (iowe),
.out_en (spi_io_out_en),
// IRQ
.spiirq (/* removing IRQ for extra SPI */),
.spiack (/* removing IRQ for extra SPI */),
// Slave Programming Mode
.por (1'b0),
.spiextload (1'b0),
.spidwrite (/*Not used*/),
.spiload (/*Not used*/),
// Outputs
.misoo (misoo),
.mosio (mosio),
.scko (scko),
.spe (spe),
.spimaster (spimaster),
// Inputs
.rst_n (rstn),
.clk (clk),
.clken (1'b1),
// Former parameters converted to inputs
.param_design_config (DESIGN_CONFIG),
.param_spcr_address (XB_SPCR_Address),
.param_spsr_address (XB_SPSR_Address),
.param_spdr_address (XB_SPDR_Address),
.clk_scki (clk_scki),
.misoi (misoi), // miso is assigned to D5
.mosii (mosii),
.scki (sckiii),
.ss_b (ss_b),
.ramadr (ramadr[7:0]),
.ramre (ramre),
.ramwe (ramwe),
.dm_sel (dm_sel)
);
// Set pin control bits for the above XB. If no XBs are being
// instantiated then leave these lines uncommented so values will
// be zeros
//
// NOTE: The xbs_* assign statements are required for every XB
// instantiated, even if it doesn't talk to the I/O. In that case
// the xbs_* busses should be tied low, as shown below.
// Here are some definitions of the signals and guidelines for
// definition:
//
// xbs_ddoe: This controls whether the xbs_ddov signal will be able
// to control the I/O pin. Setting this to a one allows xbs_ddov to
// control the pin direction.
//
// xbs_ddov: If the corresponding xbs_ddoe bit is set, then this
// controls the direction of the I/O pin. Setting xbs_ddov to a one
// will make the pin an output, setting it to a zero will make it
// an input.
//
// xbs_pvoe: This controls whether the xbs_pvov signal will be able
// to control the I/O pin. Setting this to a one allows xbs_pvov to
// control the pin value.
//
// xbs_pvov: If the corresponding xbs_pvoe bit is set, then this
// controls the value of the I/O pin. If the xbs_ddoe and xbs_ddov
// signals have set the pin to be an out put, then, if xbs_pvoe is
// set, the value of xbs_pvov will be the output value of the pin.
//
// Most often, the xbs_ddoe and xbs_ddov signals are controlled by
// the software library corresponding to the XB being
// instantiated. If the XB uses output pins, the the XB should
// provide signals as outputs from the XB that should be connected
// to the xbs_pvoe and xbs_pvov signals.
// The following was added for XLR8SPI
assign sck_ddoe = spe && ~spimaster;
assign sck_ddov = 1'b0;
assign sck_pvoe = spe && spimaster;
assign sck_pvov = scko;
assign miso_ddoe = spe;
assign miso_ddov = ~spimaster && ~ss_b;
assign miso_pvoe = spe && ~spimaster;
assign miso_pvov = misoo;
assign mosi_ddoe = spe && ~spimaster;
assign mosi_ddov = 1'b0;
assign mosi_pvoe = spe && spimaster;
assign mosi_pvov = spe && mosio;
assign ss_b_ddoe = spe && ~spimaster;
assign ss_b_ddov = 1'b0;
assign ss_b_pvoe = 1'b0;
assign ss_b_pvov = 1'b0;
// On XLR8/UNO, bus is [19:0]={portc[5:0],portb[5:0],portd[7:0]}
// Assigning the SPI to D7:D4 {sck, miso, mosi, ss_b }
assign xbs_ddoe[0] = {12'h000, {sck_ddoe,miso_ddoe,mosi_ddoe,ss_b_ddoe}, 4'h0};
assign xbs_ddov[0] = {12'h000, {sck_ddov,miso_ddov,mosi_ddov,ss_b_ddov}, 4'h0};
assign xbs_pvoe[0] = {12'h000, {sck_pvoe,miso_pvoe,mosi_pvoe,ss_b_pvoe}, 4'h0};
assign xbs_pvov[0] = {12'h000, {sck_pvov,miso_pvov,mosi_pvov,ss_b_pvov}, 4'h0};
// End of XB instantiation
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Additional XB instantiations
//
// You can add additional XB instantiations as was done above by
// repeating the above format for each additional XB. Each must
// include the instantiation of the XB module and the definition of
// the xbs_* signals.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// 5.) Combine control and busses from multiple XB instantiations
//
// Combine the pin control signals from each of the XB
// instantiations by wire ORing then to form a single set of busses
// -- \/ -- Do not edit the below lines -- \/ --
always_comb begin
// Initialize to zero
xb_ddoe = {NUM_PINS{1'b0}};
xb_ddov = {NUM_PINS{1'b0}};
xb_pvoe = {NUM_PINS{1'b0}};
xb_pvov = {NUM_PINS{1'b0}};
// Wire OR the pin control signals together
for (int i=0;i<NUM_OXBS;i++) begin
xb_ddoe = xb_ddoe | xbs_ddoe[i];
xb_ddov = xb_ddov | (xbs_ddoe[i] & xbs_ddov[i]);
xb_pvoe = xb_pvoe | xbs_pvoe[i];
xb_pvov = xb_pvov | (xbs_pvoe[i] & xbs_pvov[i]);
end
end
// -- /\ -- Do not edit the above lines -- /\ --
// Combine the dbusout and io_out_en signals from the instantiated
// XBs here and then pass them up to the xlr8_top.
//
// Here is an example for a single XB:
// assign dbus_out = xb1_out_en ? xb1_dbusout : 8'h00;
// assign io_out_en = xb1_out_en;
//
// Here is an example for three XBs (xb1, xb2 and xb3):
// assign dbus_out = xb1_out_en ? xb1_dbusout :
// xb2_out_en ? xb2_dbusout :
// xb3_out_en ? xb3_dbusout :
// 8'h00;
// assign io_out_en = xb1_out_en ||
// xb2_out_en ||
// xb3_out_en;
//
// If no XBs are being instantiated then set values to zero like
// this:
// assign dbus_out = 8'h00;
// assign io_out_en = 1'h0;
assign dbus_out = spi_io_out_en ? spi_dbusout : 8'h00;
assign io_out_en = spi_io_out_en;
// End of combining logic
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// 6.) Interrupts
//
// If you need to have interrupts for you XBs, then delete the
// following line that ties off the xb_irq output and instead
// uncomment the following instantiation of the xlr8_pcint module
assign xb_irq = 1'b0; // DELETE THIS LINE IF YOU UNCOMMENT THE XLR8_PCINT
/*
localparam NUM_INTS = 1; // EDIT to be equal to the number of interrupts
xlr8_pcint
#(
.XICR_Address (OX8ICR_Address),
.XIFR_Address (OX8IFR_Address),
.XMSK_Address (OX8MSK_Address),
.WIDTH (NUM_INTS)
)
xb_pcint_inst
(
// Clock and Reset
.rstn (rstn),
.clk (clk),
// I/O
.adr (adr),
.dbus_in (dbusin),
.dbus_out (dbus_out),
.iore (iore),
.iowe (iowe),
.out_en (io_out_en),
// DM
.ramadr (ramadr),
.ramre (ramre),
.ramwe (ramwe),
.dm_sel (dm_sel),
//
.x_int_in (), // INSERT YOUR XB INTERRUPTS HERE
.x_irq (xb_irq),
.x_irq_ack () // Don't use acks here
);
*/
endmodule // openxlr8