module POSLink( input xtal, input [3:0] tos_inputs_e2, input serial_e2, input [1:0] buttons, output tos_output, output reg data_output, output reg [3:0] anode, output reg [7:0] cathode); reg [3:0] tos_inputs_e; reg [3:0] tos_inputs; reg serial_e; reg serial; wire [3:0] tos_good; /* Synchronize inputs */ always @(posedge xtal) begin tos_inputs_e <= tos_inputs_e2; tos_inputs <= tos_inputs_e; serial_e <= serial_e2; serial <= serial_e; end wire [11:0] data; wire data_good; reg [1:0] seg; always @(*) case (seg) 2'b00: anode = 4'b0111; 2'b01: anode = 4'b1011; 2'b10: anode = 4'b1101; 2'b11: anode = 4'b1110; endcase reg [1:0] tos_select; wire [3:0] current_bit; assign tos_output = tos_inputs_e2[tos_select]; always @(*) begin cathode = data[7:0]; seg = data[9:8]; tos_select = data[11:10]; end wire [5:0] output_stuff = { buttons, tos_good }; always @(*) data_output = output_stuff[current_bit[2:0]]; TOS_Detect detect[3:0](.xtal(xtal), .tos_input(tos_inputs), .tos_good(tos_good)); POS_Serial serinput(.xtal(xtal), .serial(serial), .data_reg(data), .current_bit(current_bit), .data_good(data_good)); endmodule module POS_Serial( input xtal, input serial, output reg [11:0] data_reg = 0, output reg [3:0] current_bit = 0, output reg data_good = 0); reg serial_1a; always @(posedge xtal) serial_1a = serial; wire edge_detect = serial ^ serial_1a; reg [4:0] edge_counter = 0; always @(posedge xtal) begin data_good = 0; if (edge_detect) begin if (edge_counter == 31) begin current_bit = 0; data_reg = 0; end else begin // data_reg[11:1] = data_reg[10:0]; // data_reg[0] = (edge_counter > 20); data_reg[current_bit] = (edge_counter > 20); if (current_bit == 11) begin data_good = 1; current_bit = 0; end else current_bit = current_bit + 1; end edge_counter = 0; end else begin if (edge_counter != 31) edge_counter = edge_counter + 1; end end endmodule /* xtal: 25MHz (==40ns) * Minimum: 100ns * 2 cycles (80 ns) * Maximum: 1000ns * 25 cycles (we'll allow 30 = 1200ns for good measure) */ module TOS_Detect( input xtal, input tos_input, output reg tos_good = 0); reg tos_input_1a = 0; always @(posedge xtal) tos_input_1a <= tos_input; wire transition = tos_input ^ tos_input_1a; reg [3:0] lasttx = 0; always @(posedge xtal) begin if (transition) begin if (lasttx < 2) /* Too soon! */ tos_good <= 0; else if (lasttx > 30) /* Too late! */ tos_good <= 0; else /* OK by me. */ tos_good <= 1; lasttx <= 0; end else begin if (lasttx != 31) lasttx <= lasttx + 1; else tos_good <= 0; end end endmodule