FreeCalypso > hg > fc-sim-sniff
changeset 6:7db5fd6646df
fpga/sniffer-basic: initial version
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 21 Aug 2023 00:52:00 +0000 |
parents | 07c5aac6e84f |
children | beeda5368a77 |
files | fpga/sniffer-basic/Makefile fpga/sniffer-basic/clk_edge.v fpga/sniffer-basic/icestick.pcf fpga/sniffer-basic/reset_detect.v fpga/sniffer-basic/sniff_rx.v fpga/sniffer-basic/sync_inputs.v fpga/sniffer-basic/top.v fpga/sniffer-basic/uart_tx.v |
diffstat | 8 files changed, 285 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fpga/sniffer-basic/Makefile Mon Aug 21 00:52:00 2023 +0000 @@ -0,0 +1,18 @@ +VSRC= clk_edge.v reset_detect.v sniff_rx.v sync_inputs.v top.v uart_tx.v +PCF= icestick.pcf +PROJ= fpga + +all: ${PROJ}.bin + +${PROJ}.json: ${VSRC} + ./yosys-wrap top $@ ${VSRC} + +${PROJ}.asc: ${PROJ}.json ${PCF} + nextpnr-ice40 --hx1k --package tq144 --asc $@ --pcf ${PCF} \ + --json ${PROJ}.json + +${PROJ}.bin: ${PROJ}.asc + icepack $< $@ + +clean: + rm -f *.json *.asc *.bin
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fpga/sniffer-basic/clk_edge.v Mon Aug 21 00:52:00 2023 +0000 @@ -0,0 +1,19 @@ +/* + * This Verilog module captures the logic that detects rising edges of SIM_CLK + * for the purpose of counting them. + */ + +module clk_edge (IntClk, SIM_CLK_sync, SIM_CLK_edge); + +input IntClk; +input SIM_CLK_sync; +output SIM_CLK_edge; + +reg prev_state; + +always @(posedge IntClk) + prev_state <= SIM_CLK_sync; + +assign SIM_CLK_edge = SIM_CLK_sync && !prev_state; + +endmodule
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fpga/sniffer-basic/icestick.pcf Mon Aug 21 00:52:00 2023 +0000 @@ -0,0 +1,28 @@ +# Pin Constraint File for the HK1X FPGA as wired on the Icestick board, +# adapted for SIMtrace-ice application. + +# Board essentials +set_io CLK12 21 +set_io LED1 99 +set_io LED2 98 +set_io LED3 97 +set_io LED4 96 +set_io LED5 95 + +# FT2232H UART channel, signal names are from FT2232H DTE perspective, +# the logic in the FPGA has to act as DCE. + +set_io UART_TxD 9 +set_io UART_RxD 8 +set_io UART_RTS 7 +set_io UART_CTS 4 +set_io UART_DTR 3 +set_io UART_DSR 2 +set_io UART_DCD 1 + +# SIM sniffing interface, receiving outputs from the level shifter board +# via J1 header pins + +set_io SIM_RST 112 +set_io SIM_CLK 113 +set_io SIM_IO 114
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fpga/sniffer-basic/reset_detect.v Mon Aug 21 00:52:00 2023 +0000 @@ -0,0 +1,19 @@ +/* + * This Verilog module captures the logic that detects SIM_RST transitions + * in either direction. + */ + +module reset_detect (IntClk, SIM_RST_sync, SIM_RST_toggle); + +input IntClk; +input SIM_RST_sync; +output SIM_RST_toggle; + +reg prev_state; + +always @(posedge IntClk) + prev_state <= SIM_RST_sync; + +assign SIM_RST_toggle = SIM_RST_sync != prev_state; + +endmodule
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fpga/sniffer-basic/sniff_rx.v Mon Aug 21 00:52:00 2023 +0000 @@ -0,0 +1,62 @@ +/* + * This Verilog module captures the ISO 7816-3 character sniffing receiver. + */ + +module sniff_rx (IntClk, SIM_RST_sync, SIM_CLK_sync, SIM_IO_sync, + Rx_strobe, Rx_error, Rx_char, Rx_start_bit, Rx_parity_bit); + +input IntClk; +input SIM_RST_sync, SIM_CLK_sync, SIM_IO_sync; +output Rx_strobe, Rx_error; +output [7:0] Rx_char; +output Rx_start_bit, Rx_parity_bit; + +wire SIM_CLK_edge; + +clk_edge clk_edge (IntClk, SIM_CLK_sync, SIM_CLK_edge); + +wire [9:0] etu_0p5, etu_1p0, etu_1p5; + +/* Fi/Di=372 only for now */ +assign etu_0p5 = 10'd185; +assign etu_1p0 = 10'd371; +assign etu_1p5 = 10'd557; + +reg rx_active; +reg [9:0] clk_count; +reg [3:0] bit_count; +reg [9:0] shift_reg; + +always @(posedge IntClk) + if (!SIM_RST_sync) + rx_active <= 1'b0; + else if (!rx_active && !SIM_IO_sync) + begin + rx_active <= 1'b1; + clk_count <= etu_0p5; + bit_count <= 4'd0; + end + else if (rx_active && SIM_CLK_edge) + begin + if (clk_count != 10'd0) + clk_count <= clk_count - 10'd1; + else begin + shift_reg <= {SIM_IO_sync,shift_reg[9:1]}; + bit_count <= bit_count + 4'd1; + if (bit_count == 4'd9) + clk_count <= etu_1p5; + else + clk_count <= etu_1p0; + if (bit_count == 4'd10) + rx_active <= 1'b0; + end + end + +assign Rx_strobe = rx_active && SIM_CLK_edge && clk_count == 10'd0 && + bit_count == 4'd10; +assign Rx_error = Rx_strobe && !SIO_IO_sync; +assign Rx_char = shift_reg[8:1]; +assign Rx_start_bit = shift_reg[0]; +assign Rx_parity_bit = shift_reg[9]; + +endmodule
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fpga/sniffer-basic/sync_inputs.v Mon Aug 21 00:52:00 2023 +0000 @@ -0,0 +1,35 @@ +/* + * This Verilog module captures the input synchronizer logic: passing all 3 + * SIM sniffer inputs through double-DFF synchronizers to bring them into + * our internal clock domain. + */ + +module sync_inputs (IntClk, SIM_RST_in, SIM_RST_sync, SIM_CLK_in, SIM_CLK_sync, + SIM_IO_in, SIM_IO_sync); + +input IntClk; +input SIM_RST_in, SIM_CLK_in, SIM_IO_in; +output SIM_RST_sync, SIM_CLK_sync, SIM_IO_sync; +reg SIM_RST_sync, SIM_CLK_sync, SIM_IO_sync; + +reg SIM_RST_sync1, SIM_CLK_sync1, SIM_IO_sync1; + +always @(posedge IntClk) + SIM_RST_sync1 <= SIM_RST_in; + +always @(posedge IntClk) + SIM_RST_sync <= SIM_RST_sync1; + +always @(posedge IntClk) + SIM_CLK_sync1 <= SIM_CLK_in; + +always @(posedge IntClk) + SIM_CLK_sync <= SIM_CLK_sync1; + +always @(posedge IntClk) + SIM_IO_sync1 <= SIM_IO_in; + +always @(posedge IntClk) + SIM_IO_sync <= SIM_IO_sync1; + +endmodule
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fpga/sniffer-basic/top.v Mon Aug 21 00:52:00 2023 +0000 @@ -0,0 +1,59 @@ +module top (CLK12, LED1, LED2, LED3, LED4, LED5, UART_TxD, UART_RxD, UART_RTS, + UART_CTS, UART_DTR, UART_DSR, UART_DCD, SIM_RST, SIM_CLK, SIM_IO); + +input CLK12; +output LED1, LED2, LED3, LED4, LED5; + +input UART_TxD, UART_RTS, UART_DTR; +output UART_RxD, UART_CTS, UART_DSR, UART_DCD; + +input SIM_RST, SIM_CLK, SIM_IO; + +/* input synchronizers */ + +wire SIM_RST_sync, SIM_CLK_sync, SIM_IO_sync; + +sync_inputs sync (CLK12, SIM_RST, SIM_RST_sync, SIM_CLK, SIM_CLK_sync, + SIM_IO, SIM_IO_sync); + +/* character receiver */ + +wire Rx_strobe, Rx_error; +wire [7:0] Rx_char; +wire Rx_start_bit, Rx_parity_bit; + +sniff_rx sniff_rx (CLK12, SIM_RST_sync, SIM_CLK_sync, SIM_IO_sync, + Rx_strobe, Rx_error, Rx_char, Rx_start_bit, Rx_parity_bit); + +/* explicit detection of RST transitions */ + +wire SIM_RST_toggle; + +reset_detect reset_detect (CLK12, SIM_RST_sync, SIM_RST_toggle); + +/* output to the host */ + +wire Tx_trigger; +wire [15:0] Tx_data; + +assign Tx_trigger = Rx_strobe | SIM_RST_toggle; +assign Tx_data = {SIM_RST_toggle,SIM_RST_sync,3'b000, + Rx_error,Rx_start_bit,Rx_parity_bit,Rx_char}; + +uart_tx uart_tx (CLK12, Tx_trigger, Tx_data, UART_RxD); + +/* UART modem control outputs: unused */ + +assign UART_CTS = 1'b1; +assign UART_DSR = 1'b0; +assign UART_DCD = 1'b0; + +/* board LEDs */ + +assign LED1 = 1'b1; +assign LED2 = 1'b0; +assign LED3 = 1'b1; +assign LED4 = 1'b0; +assign LED5 = !SIM_RST; + +endmodule
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fpga/sniffer-basic/uart_tx.v Mon Aug 21 00:52:00 2023 +0000 @@ -0,0 +1,45 @@ +/* + * This Verilog module captures the UART output logic. + */ + +module uart_tx (IntClk, Tx_trigger, Tx_data, UART_out); + +input IntClk; +input Tx_trigger; +input [15:0] Tx_data; +output UART_out; +reg UART_out; + +reg tx_active; +reg [1:0] clk_div; +reg [4:0] bit_count; +reg [17:0] shift_reg; + +initial begin + tx_active = 1'b0; + UART_out = 1'b1; +end + +always @(posedge IntClk) + if (!tx_active && Tx_trigger) + begin + tx_active <= 1'b1; + UART_out <= 1'b0; + clk_div <= 2'd0; + shift_reg <= {Tx_data[15:8],2'b01,Tx_data[7:0]}; + bit_count <= 5'd0; + end + else if (tx_active) + begin + clk_div <= clk_div + 2'd1; + if (clk_div == 2'd3) + begin + UART_out <= shift_reg[0]; + shift_reg <= {1,shift_reg[17:1]}; + bit_count <= bit_count + 5'd1; + if (bit_count == 5'd19) + tx_active <= 1'b0; + end + end + +endmodule