blob: 63c315d56955592f55155204458644cf9cd95449 [file] [log] [blame]
Sylvain Munautda651572020-09-14 10:10:49 +02001/*
2 * misc.v
3 *
4 * vim: ts=4 sw=4
5 *
6 * Misc peripheral functions
7 *
8 * Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
9 * SPDX-License-Identifier: CERN-OHL-S-2.0
10 */
11
12`default_nettype none
13
14module misc (
15 // PDM outputs
16 output wire e1_vref_ct_pdm,
17 output wire e1_vref_p_pdm,
18 output wire e1_vref_n_pdm,
19
20 output wire clk_tune_hi,
21 output wire clk_tune_lo,
22
23 // Button
24 input wire btn,
25
26 // Ticks
27 input wire tick_e1_rx,
28 input wire tick_e1_tx,
29 input wire tick_usb_sof,
30
31 // Reset request
32 output wire rst_req,
33
34 // Wishbone
35 input wire [ 7:0] wb_addr,
36 output reg [31:0] wb_rdata,
37 input wire [31:0] wb_wdata,
38 input wire wb_we,
39 input wire wb_cyc,
40 output reg wb_ack,
41
42 // Clock / Reset
43 input wire clk,
44 input wire rst
45);
46
47 // Signals
48 // -------
49
50 // Bus
51 wire bus_clr;
52 reg bus_we_boot;
53 reg [ 1:0] bus_we_pdm_clk;
54 reg [ 2:0] bus_we_pdm_e1;
55
56 // Counters
57 reg [15:0] cnt_e1_rx;
58 reg [15:0] cap_e1_rx;
59 reg [15:0] cnt_e1_tx;
60 reg [15:0] cap_e1_tx;
61 reg [31:0] cnt_time;
62
63 // PDM
64 reg [12:0] pdm_clk[0:1];
65 reg [ 8:0] pdm_e1[0:2];
66
67 // Boot
68 reg [1:0] boot_sel;
69 reg boot_now;
70
71
72 // Bus interface
73 // -------------
74
75 // Ack
76 always @(posedge clk)
77 wb_ack <= wb_cyc & ~wb_ack;
78
79 assign bus_clr = ~wb_cyc | wb_ack;
80
81 // Write enables
82 always @(posedge clk)
83 if (bus_clr | ~wb_we) begin
84 bus_we_boot <= 1'b0;
85 bus_we_pdm_clk[0] <= 1'b0;
86 bus_we_pdm_clk[1] <= 1'b0;
87 bus_we_pdm_e1[0] <= 1'b0;
88 bus_we_pdm_e1[1] <= 1'b0;
89 bus_we_pdm_e1[2] <= 1'b0;
90 end else begin
91 bus_we_boot <= wb_addr == 4'h0;
92 bus_we_pdm_clk[0] <= wb_addr == 4'h8;
93 bus_we_pdm_clk[1] <= wb_addr == 4'h9;
94 bus_we_pdm_e1[0] <= wb_addr == 4'ha;
95 bus_we_pdm_e1[1] <= wb_addr == 4'hb;
96 bus_we_pdm_e1[2] <= wb_addr == 4'hc;
97 end
98
99 // Read mux
100 always @(posedge clk)
101 if (bus_clr)
102 wb_rdata <= 32'h00000000;
103 else
104 case (wb_addr[3:0])
Sylvain Munautc1d117b2020-09-15 21:57:52 +0200105 4'h4: wb_rdata <= { cap_e1_tx, cap_e1_rx };
Sylvain Munautda651572020-09-14 10:10:49 +0200106 4'h7: wb_rdata <= cnt_time;
107 4'h8: wb_rdata <= { pdm_clk[0][12], 19'h00000, pdm_clk[0][11:0] };
108 4'h9: wb_rdata <= { pdm_clk[1][12], 19'h00000, pdm_clk[1][11:0] };
109 4'ha: wb_rdata <= { pdm_e1[0][8], 23'h000000, pdm_e1[0][ 7:0] };
110 4'hb: wb_rdata <= { pdm_e1[1][8], 23'h000000, pdm_e1[1][ 7:0] };
111 4'hc: wb_rdata <= { pdm_e1[2][8], 23'h000000, pdm_e1[2][ 7:0] };
112 default: wb_rdata <= 32'hxxxxxxxx;
113 endcase
114
115
116 // Counters
117 // --------
118
119 // E1 ticks
120 always @(posedge clk or posedge rst)
121 if (rst)
122 cnt_e1_rx <= 16'h0000;
123 else if (tick_e1_rx)
124 cnt_e1_rx <= cnt_e1_rx + 1;
125
126 always @(posedge clk or posedge rst)
127 if (rst)
128 cnt_e1_tx <= 16'h0000;
129 else if (tick_e1_tx)
130 cnt_e1_tx <= cnt_e1_tx + 1;
131
132 always @(posedge clk)
133 if (tick_usb_sof) begin
134 cap_e1_rx <= cnt_e1_rx;
135 cap_e1_tx <= cnt_e1_tx;
136 end
137
138 // Time counter
139 always @(posedge clk)
140 if (rst)
141 cnt_time <= 32'h00000000;
142 else
143 cnt_time <= cnt_time + 1;
144
145
146 // PDM outputs
147 // -----------
148
149 // Registers
150 always @(posedge clk or posedge rst)
151 if (rst) begin
152 pdm_clk[0] <= 0; // 13'h1800;
153 pdm_clk[1] <= 0; // 13'h1800;
154 pdm_e1[0] <= 0; // 9'h190;
155 pdm_e1[1] <= 0; // 9'h190;
156 pdm_e1[2] <= 0; // 9'h190;
157 end else begin
158 if (bus_we_pdm_clk[0]) pdm_clk[0] <= { wb_wdata[31], wb_wdata[11:0] };
159 if (bus_we_pdm_clk[1]) pdm_clk[1] <= { wb_wdata[31], wb_wdata[11:0] };
160 if (bus_we_pdm_e1[0]) pdm_e1[0] <= { wb_wdata[31], wb_wdata[ 7:0] };
161 if (bus_we_pdm_e1[1]) pdm_e1[1] <= { wb_wdata[31], wb_wdata[ 7:0] };
162 if (bus_we_pdm_e1[2]) pdm_e1[2] <= { wb_wdata[31], wb_wdata[ 7:0] };
163 end
164
165 // PDM cores
166 pdm #(
167 .WIDTH(12),
168 .PHY("ICE40"),
169 .DITHER("YES")
170 ) pdm_clk_I[1:0] (
171 .pdm ({ clk_tune_hi, clk_tune_lo }),
172 .cfg_val({ pdm_clk[1][11:0], pdm_clk[0][11:0] }),
173 .cfg_oe ({ pdm_clk[1][12], pdm_clk[0][12] }),
174 .clk (clk),
175 .rst (rst)
176 );
177
178 pdm #(
179 .WIDTH(8),
180 .PHY("ICE40"),
181 .DITHER("NO")
182 ) pdm_e1_I[2:0] (
183 .pdm ({ e1_vref_ct_pdm, e1_vref_p_pdm, e1_vref_n_pdm }),
184 .cfg_val({ pdm_e1[2][7:0], pdm_e1[1][7:0], pdm_e1[0][7:0] }),
185 .cfg_oe ({ pdm_e1[2][8], pdm_e1[1][8], pdm_e1[0][8] }),
186 .clk (clk),
187 .rst (rst)
188 );
189
190
191 // DFU / Reboot
192 // ------------
193
194 always @(posedge clk or posedge rst)
195 if (rst) begin
196 boot_now <= 1'b0;
197 boot_sel <= 2'b00;
198 end else if (bus_we_boot) begin
199 boot_now <= wb_wdata[2];
200 boot_sel <= wb_wdata[1:0];
201 end
202
203 dfu_helper #(
204 .TIMER_WIDTH(26),
205 .BTN_MODE(3),
206 .DFU_MODE(0)
207 ) dfu_I (
208 .boot_sel(boot_sel),
209 .boot_now(boot_now),
210 .btn_pad (btn),
211 .btn_val (),
212 .rst_req (rst_req),
213 .clk (clk),
214 .rst (rst)
215 );
216
217endmodule // misc