-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathiua_icebreaker_top.v
147 lines (120 loc) · 2.58 KB
/
iua_icebreaker_top.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
/*
* iua_icebreaker_top.v
*
* ice40 USB Analyzer - Top Level for iCEBreaker board
*
* Copyright (C) 2019 Sylvain Munaut <[email protected]>
*
* vim: ts=4 sw=4
*/
`ifdef SIM
`default_nettype none
`endif
module iua_icebreaker_top (
// USB input
input wire usb_dp_pad,
input wire usb_dn_pad,
// Serial interface
output wire uart_tx,
input wire uart_rx,
// Status LEDs
output wire [2:0] led,
// External clock
input wire clk_in
);
// Signals
// -------
// UART lines
wire uart_tx_i;
wire uart_rx_i;
// Clocks / Reset
wire rst_req;
reg rst_in = 1'b0;
wire clk;
wire rst;
// Actual Logic Analyzer
// ---------------------
iua_top #(
.SERIAL_DIV(23) // 48 MHz / (23+1) = 2Mbaud
) iua_I (
.usb_dp_pad(usb_dp_pad),
.usb_dn_pad(usb_dn_pad),
.uart_tx(uart_tx_i),
.uart_rx(uart_rx_i),
.clk(clk),
.rst(rst)
);
assign uart_rx_i = uart_rx;
assign uart_tx = uart_tx_i;
// Clock and Reset generation
// --------------------------
iua_sysmgr #(
// PLL setup to go from 12M to 48M
.DIVR(4'b0000), // DIVR = 0
.DIVF(7'b0111111), // DIVF = 63
.DIVQ(3'b100), // DIVQ = 4
.FILTER_RANGE(3'b001) // FILTER_RANGE = 1
) sysmgr_I (
.clk_in(clk_in),
.rst_in(rst_in),
.clk_out(clk),
.rst_out(rst)
);
always @(posedge clk, posedge rst)
if (rst)
rst_in <= 1'b0;
else
rst_in <= rst_in | rst_req;
assign rst_req = 1'b0; // FIXME
// Status LEDS
// -----------
reg dbg_started;
reg dbg_uart_tx;
reg dbg_uart_toggle;
reg [24:0] dbg_cnt;
reg [15:0] dbg_running;
wire [2:0] led_ctrl;
// Status bit
always @(posedge clk)
if (rst)
dbg_started <= 1'b0;
else if (clk)
dbg_started <= 1'b1;
// Status counter
always @(posedge clk)
if (rst)
dbg_cnt <= 0;
else if (clk)
dbg_cnt <= dbg_cnt + 1;
// Detect data is flowing
always @(posedge clk)
begin
dbg_uart_tx <= uart_tx_i;
dbg_uart_toggle <= uart_tx_i ^ dbg_uart_tx;
end
always @(posedge clk)
if (rst)
dbg_running <= 0;
else
dbg_running <= dbg_uart_toggle ? 16'hffff : (dbg_running - dbg_running[15]);
// Monitoring
assign led_ctrl[0] = dbg_started & (dbg_cnt[1:0] == 2'b00);
assign led_ctrl[1] = dbg_running[15] & (dbg_cnt[1:0] == 2'b00) & dbg_cnt[24];
assign led_ctrl[2] = rst | rst_in;
// Hardware LED driver
SB_RGBA_DRV #(
.CURRENT_MODE("0b1"),
.RGB0_CURRENT("0b000001"),
.RGB1_CURRENT("0b000001"),
.RGB2_CURRENT("0b000001")
) led_I (
.RGBLEDEN(1'b1),
.RGB0PWM(led_ctrl[0]),
.RGB1PWM(led_ctrl[1]),
.RGB2PWM(led_ctrl[2]),
.CURREN(1'b1),
.RGB0(led[0]), // Green
.RGB1(led[1]), // Blue
.RGB2(led[2]) // Red
);
endmodule // iua_top