gateware: Rework the low-level line state monitoring ticks

The 'tick' system was meant to allow the firmware to monitor the
low level state of the line, beyong just "not aligned", but it was
never really useful in the present state.

Now we have more tick source available (but only one can be measured
at the same time). More specifically, the firmware can monitor the
presence/absence of raw pulses (LOS condition), it can also monitor
the number of '1' pulses to detect an AIS signals, or simply the rate
of RX pulses (to tune the local oscillator to incoming signal rate).

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Change-Id: I31fa8a717a26643f1b6ca5644bee1d8c41a2512e
This commit is contained in:
Sylvain Munaut 2024-04-29 16:14:54 +02:00
parent 4858825594
commit be4564a224
11 changed files with 156 additions and 65 deletions

View File

@ -72,9 +72,8 @@ module soc_base #(
input wire [ WB_N -1:0] wb_m_ack,
// Ticks
output wire [E1_N-1:0] tick_e1_rx,
output wire [E1_N-1:0] tick_e1_tx,
output wire tick_usb_sof,
output wire [4*E1_N-1:0] tick_e1,
output wire tick_usb_sof,
// Clock / Reset
input wire clk_sys,
@ -502,8 +501,7 @@ module soc_base #(
.wb_cyc (wb_cyc[7]),
.wb_ack (wb_ack[7]),
.irq (),
.tick_rx (tick_e1_rx),
.tick_tx (tick_e1_tx),
.mon_tick (tick_e1),
.clk (clk_sys),
.rst (rst_sys)
);

@ -1 +1 @@
Subproject commit 7caecb33922c85b803715eecf4464953c3e6615d
Subproject commit 82040f15ec54a6e22d9ad72cdcd72af37f3961dd

View File

@ -156,21 +156,43 @@ Collection of small auxiliary peripherals.
Write to this register with bit 2 set will trigger a FPGA reload of the selected image.
#### E1 tick channel 0/1 (Read Only, addr `0x04` / `0x05`)
#### E1 tick source select (Write Only, addr `0x04`)
```text
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
| / | rx_tick |
| / |ts[1]| / |ts[0]|
'-----------------------------------------------------------------------------------------------'
* [15:0] - rx_tick
* [17:16] - ts[1] : Tick Source for channel 1
* [ 1: 0] - ts[0] : Tick Source for channel 0
```
An internal counter is incremented at every bit received by the corresponding E1 channel. That
counter value is then captured at every USB Start-of-Frame packet and the last captured value
made available here.
Selects the tick source for the counters below for each E1 channel.
Available sources are :
* `0`: (reserved)
* `1`: (reserved)
* `2`: RX Sample, for every bit received
* `3`: RX One, for every `1` bit received
#### E1 tick counters (Read Only, addr `0x04`)
```text
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
| chan[1] | chan[0] |
'-----------------------------------------------------------------------------------------------'
* [31:16] - chan[1] : Tick counter for channel 1
* [15: 0] - chan[0] : Tick counter for channel 0
```
An internal counter is incremented at every E1 tick (tick source selected above) for each E1
channel. That counter value is then captured at every USB Start-of-Frame packet and the last
captured value made available here.
#### Time (Read Only, addr `0x07`)

View File

@ -16,7 +16,7 @@ module misc (
input wire btn,
// Ticks
input wire [1:0] tick_e1_rx,
input wire [7:0] tick_e1,
input wire tick_usb_sof,
// Reset request
@ -43,9 +43,13 @@ module misc (
// Bus
wire bus_clr;
reg bus_we_boot;
reg bus_we_tick_sel;
// Counters
wire [15:0] cap_e1_rx[0:1];
reg [1:0] tick_e1_sel[0:1];
wire [1:0] tick_e1_mux;
wire [15:0] cap_e1[0:1];
wire [31:0] cnt_time;
// Boot
@ -64,10 +68,13 @@ module misc (
// Write enables
always @(posedge clk)
if (bus_clr | ~wb_we)
bus_we_boot <= 1'b0;
else
bus_we_boot <= wb_addr == 4'h0;
if (bus_clr | ~wb_we) begin
bus_we_boot <= 1'b0;
bus_we_tick_sel <= 1'b0;
end else begin
bus_we_boot <= wb_addr == 4'h0;
bus_we_tick_sel <= wb_addr == 4'h4;
end
// Read mux
always @(posedge clk)
@ -75,8 +82,7 @@ module misc (
wb_rdata <= 32'h00000000;
else
case (wb_addr[3:0])
4'h4: wb_rdata <= { 16'h000, cap_e1_rx[0] };
4'h5: wb_rdata <= { 16'h000, cap_e1_rx[1] };
4'h4: wb_rdata <= { cap_e1[1], cap_e1[0] };
4'h7: wb_rdata <= cnt_time;
default: wb_rdata <= 32'hxxxxxxxx;
endcase
@ -86,12 +92,21 @@ module misc (
// --------
// E1 ticks
always @(posedge clk)
if (bus_we_tick_sel) begin
tick_e1_sel[1] <= wb_wdata[17:16];
tick_e1_sel[0] <= wb_wdata[ 1: 0];
end
assign tick_e1_mux[0] = tick_e1[{1'b0, tick_e1_sel[0]}];
assign tick_e1_mux[1] = tick_e1[{1'b1, tick_e1_sel[1]}];
capcnt #(
.W(16)
) e1_cnt_I[1:0] (
.cnt_cur (),
.cnt_cap ({cap_e1_rx[1], cap_e1_rx[0] }),
.inc ({tick_e1_rx[1], tick_e1_rx[0]}),
.cnt_cap ({ cap_e1[1], cap_e1[0] }),
.inc ({ tick_e1_mux[1], tick_e1_mux[0] }),
.cap (tick_usb_sof),
.clk (clk),
.rst (rst)

View File

@ -80,7 +80,7 @@ module top (
wire [(WB_N*32)-1:0] wb_rdata_flat;
// Ticks
wire [1:0] tick_e1_rx;
wire [7:0] tick_e1;
wire tick_usb_sof;
// Clocks / Reset
@ -136,7 +136,7 @@ module top (
.wb_m_we (wb_we),
.wb_m_cyc (wb_cyc),
.wb_m_ack (wb_ack),
.tick_e1_rx (tick_e1_rx),
.tick_e1 (tick_e1),
.tick_usb_sof (tick_usb_sof),
.clk_sys (clk_sys),
.rst_sys (rst_sys),
@ -167,7 +167,7 @@ module top (
misc misc_I (
.btn (btn),
.tick_e1_rx (tick_e1_rx),
.tick_e1 (tick_e1),
.tick_usb_sof (tick_usb_sof),
.rst_req (rst_req),
.wb_addr (wb_addr[7:0]),

View File

@ -156,20 +156,39 @@ Collection of small auxiliary peripherals.
Write to this register with bit 2 set will trigger a FPGA reload of the selected image.
#### E1 tick channel 0 (Read Only, addr `0x04`)
#### E1 tick source select (Write Only, addr `0x04`)
```text
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
| tx_tick | rx_tick |
| / | tss |
'-----------------------------------------------------------------------------------------------'
* [31:16] - tx_tick
* [15: 0] - rx_tick
* [ 1: 0] - tss : Tick Source Select
```
An internal counter is incremented at every bit received/transmitted by the corresponding E1
Selects the tick source for the counters below.
Available sources are :
* `0`: TX tick, for every bit sent
* `1`: RX Pulse, for every detected pulse on the input
* `2`: RX Sample, for every bit received
* `3`: RX One, for every `1` bit received
#### E1 tick counters (Read Only, addr `0x04`)
```text
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
| / | tick_cnt |
'-----------------------------------------------------------------------------------------------'
* [15: 0] - tick_cnt : Tick counter value
```
An internal counter is incremented at every E1 tick (tick source selected above) for each E1
channel. That counter value is then captured at every USB Start-of-Frame packet and the last
captured value made available here.

View File

@ -26,9 +26,8 @@ module misc (
input wire btn,
// Ticks
input wire tick_e1_rx,
input wire tick_e1_tx,
input wire tick_usb_sof,
input wire [3:0] tick_e1,
input wire tick_usb_sof,
// Reset request
output wire rst_req,
@ -52,12 +51,15 @@ module misc (
// Bus
wire bus_clr;
reg bus_we_boot;
reg bus_we_tick_sel;
reg [ 1:0] bus_we_pdm_clk;
reg [ 2:0] bus_we_pdm_e1;
// Counters
wire [15:0] cap_e1_rx;
wire [15:0] cap_e1_tx;
reg [1:0] tick_e1_sel;
wire tick_e1_mux;
wire [15:0] cap_e1;
wire [31:0] cnt_time;
// PDM
@ -82,6 +84,7 @@ module misc (
always @(posedge clk)
if (bus_clr | ~wb_we) begin
bus_we_boot <= 1'b0;
bus_we_tick_sel <= 1'b0;
bus_we_pdm_clk[0] <= 1'b0;
bus_we_pdm_clk[1] <= 1'b0;
bus_we_pdm_e1[0] <= 1'b0;
@ -89,6 +92,7 @@ module misc (
bus_we_pdm_e1[2] <= 1'b0;
end else begin
bus_we_boot <= wb_addr == 4'h0;
bus_we_tick_sel <= wb_addr == 4'h4;
bus_we_pdm_clk[0] <= wb_addr == 4'h8;
bus_we_pdm_clk[1] <= wb_addr == 4'h9;
bus_we_pdm_e1[0] <= wb_addr == 4'ha;
@ -102,7 +106,7 @@ module misc (
wb_rdata <= 32'h00000000;
else
case (wb_addr[3:0])
4'h4: wb_rdata <= { cap_e1_tx, cap_e1_rx };
4'h4: wb_rdata <= { 16'h0000, cap_e1 };
4'h7: wb_rdata <= cnt_time;
`ifdef WITH_PDM_READBACK
4'h8: wb_rdata <= { pdm_clk[0][12], 19'h00000, pdm_clk[0][11:0] };
@ -119,12 +123,18 @@ module misc (
// --------
// E1 ticks
always @(posedge clk)
if (bus_we_tick_sel)
tick_e1_sel <= wb_wdata[1:0];
assign tick_e1_mux = tick_e1[tick_e1_sel];
capcnt #(
.W(16)
) e1_cnt_I[1:0] (
) e1_cnt_I (
.cnt_cur (),
.cnt_cap ({cap_e1_tx, cap_e1_rx }),
.inc ({tick_e1_tx, tick_e1_rx}),
.cnt_cap (cap_e1),
.inc (tick_e1_mux),
.cap (tick_usb_sof),
.clk (clk),
.rst (rst)

View File

@ -78,8 +78,7 @@ module top (
wire [(WB_N*32)-1:0] wb_rdata_flat;
// Ticks
wire tick_e1_rx;
wire tick_e1_tx;
wire [3:0] tick_e1;
wire tick_usb_sof;
// Clocks / Reset
@ -135,8 +134,7 @@ module top (
.wb_m_we (wb_we),
.wb_m_cyc (wb_cyc),
.wb_m_ack (wb_ack),
.tick_e1_rx (tick_e1_rx),
.tick_e1_tx (tick_e1_tx),
.tick_e1 (tick_e1),
.tick_usb_sof (tick_usb_sof),
.clk_sys (clk_sys),
.rst_sys (rst_sys),
@ -172,8 +170,7 @@ module top (
.clk_tune_hi (clk_tune_hi),
.clk_tune_lo (clk_tune_lo),
.btn (btn),
.tick_e1_rx (tick_e1_rx),
.tick_e1_tx (tick_e1_tx),
.tick_e1 (tick_e1),
.tick_usb_sof (tick_usb_sof),
.rst_req (rst_req),
.wb_addr (wb_addr[7:0]),

View File

@ -206,20 +206,41 @@ Each LED can have 4 mode :
* `10`: Slow blink
* `11`: Fast blink
#### E1 tick channel 0/1 (Read Only, addr `0x04-0x05`)
#### E1 tick source select (Write Only, addr `0x04`)
```text
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
| tx_tick | rx_tick |
| / |ts[1]| / |ts[0]|
'-----------------------------------------------------------------------------------------------'
* [31:16] - tx_tick
* [15: 0] - rx_tick
* [17:16] - ts[1] : Tick Source for channel 1
* [ 1: 0] - ts[0] : Tick Source for channel 0
```
An internal counter is incremented at every bit received/transmitted by the corresponding E1
Selects the tick source for the counters below for each E1 channel.
Available sources are :
* `0`: TX tick, for every bit sent
* `1`: RX Pulse, for every detected pulse on the input
* `2`: RX Sample, for every bit received
* `3`: RX One, for every `1` bit received
#### E1 tick counters (Read Only, addr `0x04`)
```text
,-----------------------------------------------------------------------------------------------,
|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
|-----------------------------------------------------------------------------------------------|
| chan[1] | chan[0] |
'-----------------------------------------------------------------------------------------------'
* [31:16] - chan[1] : Tick counter for channel 1
* [15: 0] - chan[0] : Tick counter for channel 0
```
An internal counter is incremented at every E1 tick (tick source selected above) for each E1
channel. That counter value is then captured at every USB Start-of-Frame packet and the last
captured value made available here.

View File

@ -37,8 +37,7 @@ module misc (
input wire btn_stb,
// Ticks
input wire [ 1:0] tick_e1_rx,
input wire [ 1:0] tick_e1_tx,
input wire [ 7:0] tick_e1,
input wire tick_usb_sof,
// Reset request
@ -67,6 +66,7 @@ module misc (
reg bus_we_boot;
reg bus_we_gpio;
reg bus_we_led;
reg bus_we_tick_sel;
reg [ 1:0] bus_we_pdm_clk;
reg [ 1:0] bus_we_pdm_e1;
@ -83,8 +83,10 @@ module misc (
wire gps_pps_r;
// Counters
wire [15:0] cap_e1_rx[0:1];
wire [15:0] cap_e1_tx[0:1];
reg [1:0] tick_e1_sel[0:1];
wire [1:0] tick_e1_mux;
wire [15:0] cap_e1[0:1];
wire [31:0] cap_gps;
wire [31:0] cnt_time;
@ -112,6 +114,7 @@ module misc (
bus_we_boot <= 1'b0;
bus_we_gpio <= 1'b0;
bus_we_led <= 1'b0;
bus_we_tick_sel <= 1'b0;
bus_we_pdm_clk[0] <= 1'b0;
bus_we_pdm_clk[1] <= 1'b0;
bus_we_pdm_e1[0] <= 1'b0;
@ -120,6 +123,7 @@ module misc (
bus_we_boot <= wb_addr == 4'h0;
bus_we_gpio <= wb_addr == 4'h1;
bus_we_led <= wb_addr == 4'h2;
bus_we_tick_sel <= wb_addr == 4'h4;
bus_we_pdm_clk[0] <= wb_addr == 4'h8;
bus_we_pdm_clk[1] <= wb_addr == 4'h9;
bus_we_pdm_e1[0] <= wb_addr == 4'ha;
@ -134,8 +138,7 @@ module misc (
case (wb_addr[3:0])
4'h1: wb_rdata <= { 12'h000, gpio_in, 4'h0, gpio_oe, 4'h0, gpio_out };
4'h2: wb_rdata <= { 22'h000000, e1_led_active, e1_led };
4'h4: wb_rdata <= { cap_e1_tx[0], cap_e1_rx[0] };
4'h5: wb_rdata <= { cap_e1_tx[1], cap_e1_rx[1] };
4'h4: wb_rdata <= { cap_e1[1], cap_e1[0] };
4'h6: wb_rdata <= cap_gps;
4'h7: wb_rdata <= cnt_time;
`ifdef WITH_PDM_READBACK
@ -229,12 +232,21 @@ module misc (
// --------
// E1 ticks
always @(posedge clk)
if (bus_we_tick_sel) begin
tick_e1_sel[1] <= wb_wdata[17:16];
tick_e1_sel[0] <= wb_wdata[ 1: 0];
end
assign tick_e1_mux[0] = tick_e1[{1'b0, tick_e1_sel[0]}];
assign tick_e1_mux[1] = tick_e1[{1'b1, tick_e1_sel[1]}];
capcnt #(
.W(16)
) e1_cnt_I[3:0] (
) e1_cnt_I[1:0] (
.cnt_cur (),
.cnt_cap ({cap_e1_tx[1], cap_e1_rx[1], cap_e1_tx[0], cap_e1_rx[0] }),
.inc ({tick_e1_tx[1], tick_e1_rx[1], tick_e1_tx[0], tick_e1_rx[0]}),
.cnt_cap ({ cap_e1[1], cap_e1[0] }),
.inc ({ tick_e1_mux[1], tick_e1_mux[0] }),
.cap (tick_usb_sof),
.clk (clk),
.rst (rst)

View File

@ -99,8 +99,7 @@ module top (
wire [(WB_N*32)-1:0] wb_rdata_flat;
// Ticks
wire [1:0] tick_e1_rx;
wire [1:0] tick_e1_tx;
wire [7:0] tick_e1;
wire tick_usb_sof;
// I2C
@ -182,8 +181,7 @@ module top (
.wb_m_we (wb_we),
.wb_m_cyc (wb_cyc),
.wb_m_ack (wb_ack),
.tick_e1_rx (tick_e1_rx),
.tick_e1_tx (tick_e1_tx),
.tick_e1 (tick_e1),
.tick_usb_sof (tick_usb_sof),
.clk_sys (clk_sys),
.rst_sys (rst_sys),
@ -255,8 +253,7 @@ module top (
.e1_led_active (e1_led_active),
.btn_val (btn_val),
.btn_stb (btn_stb),
.tick_e1_rx (tick_e1_rx),
.tick_e1_tx (tick_e1_tx),
.tick_e1 (tick_e1),
.tick_usb_sof (tick_usb_sof),
.rst_req (rst_req),
.wb_addr (wb_addr[7:0]),