blob: 934ba0559f06928ba57cc7694c850c0062d61857 [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
Sylvain Munautff0ab3e2020-10-03 20:15:28 +020057 wire [15:0] cap_e1_rx;
58 wire [15:0] cap_e1_tx;
59 wire [31:0] cnt_time;
Sylvain Munautda651572020-09-14 10:10:49 +020060
61 // PDM
62 reg [12:0] pdm_clk[0:1];
63 reg [ 8:0] pdm_e1[0:2];
64
65 // Boot
66 reg [1:0] boot_sel;
67 reg boot_now;
68
69
70 // Bus interface
71 // -------------
72
73 // Ack
74 always @(posedge clk)
75 wb_ack <= wb_cyc & ~wb_ack;
76
77 assign bus_clr = ~wb_cyc | wb_ack;
78
79 // Write enables
80 always @(posedge clk)
81 if (bus_clr | ~wb_we) begin
82 bus_we_boot <= 1'b0;
83 bus_we_pdm_clk[0] <= 1'b0;
84 bus_we_pdm_clk[1] <= 1'b0;
85 bus_we_pdm_e1[0] <= 1'b0;
86 bus_we_pdm_e1[1] <= 1'b0;
87 bus_we_pdm_e1[2] <= 1'b0;
88 end else begin
89 bus_we_boot <= wb_addr == 4'h0;
90 bus_we_pdm_clk[0] <= wb_addr == 4'h8;
91 bus_we_pdm_clk[1] <= wb_addr == 4'h9;
92 bus_we_pdm_e1[0] <= wb_addr == 4'ha;
93 bus_we_pdm_e1[1] <= wb_addr == 4'hb;
94 bus_we_pdm_e1[2] <= wb_addr == 4'hc;
95 end
96
97 // Read mux
98 always @(posedge clk)
99 if (bus_clr)
100 wb_rdata <= 32'h00000000;
101 else
102 case (wb_addr[3:0])
Sylvain Munautc1d117b2020-09-15 21:57:52 +0200103 4'h4: wb_rdata <= { cap_e1_tx, cap_e1_rx };
Sylvain Munautda651572020-09-14 10:10:49 +0200104 4'h7: wb_rdata <= cnt_time;
105 4'h8: wb_rdata <= { pdm_clk[0][12], 19'h00000, pdm_clk[0][11:0] };
106 4'h9: wb_rdata <= { pdm_clk[1][12], 19'h00000, pdm_clk[1][11:0] };
107 4'ha: wb_rdata <= { pdm_e1[0][8], 23'h000000, pdm_e1[0][ 7:0] };
108 4'hb: wb_rdata <= { pdm_e1[1][8], 23'h000000, pdm_e1[1][ 7:0] };
109 4'hc: wb_rdata <= { pdm_e1[2][8], 23'h000000, pdm_e1[2][ 7:0] };
110 default: wb_rdata <= 32'hxxxxxxxx;
111 endcase
112
113
114 // Counters
115 // --------
116
117 // E1 ticks
Sylvain Munautff0ab3e2020-10-03 20:15:28 +0200118 capcnt #(
119 .W(16)
120 ) e1_cnt_I[1:0] (
121 .cnt_cur (),
122 .cnt_cap ({cap_e1_tx, cap_e1_rx }),
123 .inc ({tick_e1_tx, tick_e1_rx}),
124 .cap (tick_usb_sof),
125 .clk (clk),
126 .rst (rst)
127 );
Sylvain Munautda651572020-09-14 10:10:49 +0200128
Sylvain Munautff0ab3e2020-10-03 20:15:28 +0200129 // Time
130 capcnt #(
131 .W(32)
132 ) time_cnt_I (
133 .cnt_cur (cnt_time),
134 .cnt_cap (),
135 .inc (1'b1),
136 .cap (1'b0),
137 .clk (clk),
138 .rst (rst)
139 );
Sylvain Munautda651572020-09-14 10:10:49 +0200140
141
142 // PDM outputs
143 // -----------
144
145 // Registers
146 always @(posedge clk or posedge rst)
147 if (rst) begin
148 pdm_clk[0] <= 0; // 13'h1800;
149 pdm_clk[1] <= 0; // 13'h1800;
150 pdm_e1[0] <= 0; // 9'h190;
151 pdm_e1[1] <= 0; // 9'h190;
152 pdm_e1[2] <= 0; // 9'h190;
153 end else begin
154 if (bus_we_pdm_clk[0]) pdm_clk[0] <= { wb_wdata[31], wb_wdata[11:0] };
155 if (bus_we_pdm_clk[1]) pdm_clk[1] <= { wb_wdata[31], wb_wdata[11:0] };
156 if (bus_we_pdm_e1[0]) pdm_e1[0] <= { wb_wdata[31], wb_wdata[ 7:0] };
157 if (bus_we_pdm_e1[1]) pdm_e1[1] <= { wb_wdata[31], wb_wdata[ 7:0] };
158 if (bus_we_pdm_e1[2]) pdm_e1[2] <= { wb_wdata[31], wb_wdata[ 7:0] };
159 end
160
161 // PDM cores
162 pdm #(
163 .WIDTH(12),
164 .PHY("ICE40"),
165 .DITHER("YES")
166 ) pdm_clk_I[1:0] (
167 .pdm ({ clk_tune_hi, clk_tune_lo }),
168 .cfg_val({ pdm_clk[1][11:0], pdm_clk[0][11:0] }),
169 .cfg_oe ({ pdm_clk[1][12], pdm_clk[0][12] }),
170 .clk (clk),
171 .rst (rst)
172 );
173
174 pdm #(
175 .WIDTH(8),
176 .PHY("ICE40"),
177 .DITHER("NO")
178 ) pdm_e1_I[2:0] (
179 .pdm ({ e1_vref_ct_pdm, e1_vref_p_pdm, e1_vref_n_pdm }),
180 .cfg_val({ pdm_e1[2][7:0], pdm_e1[1][7:0], pdm_e1[0][7:0] }),
181 .cfg_oe ({ pdm_e1[2][8], pdm_e1[1][8], pdm_e1[0][8] }),
182 .clk (clk),
183 .rst (rst)
184 );
185
186
187 // DFU / Reboot
188 // ------------
189
190 always @(posedge clk or posedge rst)
191 if (rst) begin
192 boot_now <= 1'b0;
193 boot_sel <= 2'b00;
194 end else if (bus_we_boot) begin
195 boot_now <= wb_wdata[2];
196 boot_sel <= wb_wdata[1:0];
197 end
198
199 dfu_helper #(
200 .TIMER_WIDTH(26),
201 .BTN_MODE(3),
202 .DFU_MODE(0)
203 ) dfu_I (
204 .boot_sel(boot_sel),
205 .boot_now(boot_now),
206 .btn_pad (btn),
207 .btn_val (),
208 .rst_req (rst_req),
209 .clk (clk),
210 .rst (rst)
211 );
212
213endmodule // misc