view fpga/sniffer-pps/sniff_rx.v @ 58:95ed46b5f8f1 default tip

doc/Sniffing-hw-setup: mv-sniffer is here
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 04 Oct 2023 05:55:09 +0000
parents ab37fcb71744
children
line wrap: on
line source

/*
 * 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,
		 speed_enh_mode, speed_enh_mult);

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;
input speed_enh_mode;
input [1:0] speed_enh_mult;

wire SIM_CLK_edge;

clk_edge clk_edge (IntClk, SIM_CLK_sync, SIM_CLK_edge);

reg [9:0] etu_0p5, etu_1p0, etu_1p5;	/* combinational */

always @*
	casez ({speed_enh_mode,speed_enh_mult})
		3'b0??:
		    begin
			/* F/D = 372 */
			etu_0p5 = 10'd185;
			etu_1p0 = 10'd371;
			etu_1p5 = 10'd557;
		    end
		3'b100:
		    begin
			/* F/D = 64 */
			etu_0p5 = 10'd31;
			etu_1p0 = 10'd63;
			etu_1p5 = 10'd95;
		    end
		3'b101:
		    begin
			/* F/D = 32 */
			etu_0p5 = 10'd15;
			etu_1p0 = 10'd31;
			etu_1p5 = 10'd47;
		    end
		3'b110:
		    begin
			/* F/D = 16 */
			etu_0p5 = 10'd7;
			etu_1p0 = 10'd15;
			etu_1p5 = 10'd23;
		    end
		3'b111:
		    begin
			/* F/D = 8 */
			etu_0p5 = 10'd3;
			etu_1p0 = 10'd7;
			etu_1p5 = 10'd11;
		    end
	endcase

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 && !SIM_IO_sync;
assign Rx_char = shift_reg[8:1];
assign Rx_start_bit = shift_reg[0];
assign Rx_parity_bit = shift_reg[9];

endmodule