TARGET = POSLink
VLOGS = POSLink.v
VLOGS_ALL = $(VLOGS)
+CHIP = xc9572xl-7-vq44
all: fpga_target
-scancodes.unshifted.hex: scancodes.txt
- cut -f3 -d, scancodes.txt > scancodes.unshifted.hex
-
-scancodes.shifted.hex: scancodes.txt
- cut -f4 -d, scancodes.txt > scancodes.shifted.hex
-
BITGEN_OPTS = \
-w \
-g DebugBitstream:No \
-g DonePipe:No \
-g DriveDone:No
-fpga_target: $(TARGET).svf
+fpga_target: $(TARGET).vm6
$(TARGET).ngc: $(TARGET).xst $(VLOGS_ALL)
@mkdir -p xst/projnav.tmp
xst -ifn $(TARGET).xst -ofn $(TARGET).syr
$(TARGET).ngd: $(TARGET).ngc $(TARGET).ucf
- ngdbuild -dd _ngo -uc $(TARGET).ucf -nt timestamp -p xc3s1200e-fg320-5 "$(TARGET).ngc" $(TARGET).ngd
+ ngdbuild -dd _ngo -uc $(TARGET).ucf -nt timestamp -p $(CHIP) "$(TARGET).ngc" $(TARGET).ngd
+
+$(TARGET).vm6: $(TARGET).ngd
+ cpldfit -p $(CHIP) -power std $(TARGET).ngd -inputs 10
$(TARGET)_map.ncd: $(TARGET).ngd
- map -p xc3s1200e-fg320-5 -cm area -pr off -k 4 -c 100 -o $(TARGET)_map.ncd $(TARGET).ngd $(TARGET).pcf
+ map -p $(CHIP) -cm area -pr off -k 4 -c 100 -o $(TARGET)_map.ncd $(TARGET).ngd $(TARGET).pcf
$(TARGET).ncd: $(TARGET)_map.ncd
par -w -ol std -t 1 $(TARGET)_map.ncd $(TARGET).ncd $(TARGET).pcf
-NET "xtal" LOC="b8";
+NET "xtal" LOC="P1";
+NET "xtal" BUFG=CLK;
-NET "tos_inputs_e2<0>" LOC="H16";
-NET "tos_inputs_e2<1>" LOC="G13";
-NET "tos_inputs_e2<2>" LOC="J16";
-NET "tos_output" LOC="G15";
-NET "leds<0>" LOC="J14";
-NET "leds<1>" LOC="J15";
-NET "leds<2>" LOC="K15";
-NET "leds<3>" LOC="K14";
-NET "sw<0>" LOC="G18";
-NET "sw<1>" LOC="H18";
-NET "sw<2>" LOC="K18";
-NET "sw<3>" LOC="K17";
+NET "tos_inputs_e2<0>" LOC="P38";
+NET "tos_inputs_e2<1>" LOC="P39";
+NET "tos_inputs_e2<2>" LOC="P32";
+NET "tos_inputs_e2<3>" LOC="P31";
+NET "tos_output" LOC="P30";
+NET "data_output" LOC="P5";
+NET "serial_e2" LOC="P2";
+NET "anode<0>" LOC="P29";
+NET "anode<1>" LOC="P28";
+NET "anode<2>" LOC="P23";
+NET "anode<3>" LOC="P22";
+NET "buttons<0>" LOC="P7";
+NET "buttons<1>" LOC="P6";
+NET "cathode<0>" LOC="P19";
+NET "cathode<1>" LOC="P18";
+NET "cathode<2>" LOC="P13";
+NET "cathode<3>" LOC="P12";
+NET "cathode<4>" LOC="P8";
+NET "cathode<5>" LOC="P20";
+NET "cathode<6>" LOC="P21";
+NET "cathode<7>" LOC="P14";
module POSLink(
input xtal,
- input [2:0] tos_inputs_e2,
- input [3:0] sw,
- output reg [3:0] leds,
- output reg tos_output);
-
- reg [2:0] tos_inputs_e;
- reg [2:0] tos_inputs;
- wire [2:0] tos_good;
+ 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
-
- /* 100ns -> 1000ns */
-
+
+ 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
- leds[3:0] = 4'h0;
-
- if (sw[2] || (tos_good[2] && ~sw[1] && ~sw[0])) begin
- tos_output = tos_inputs[2];
- leds[2] = 1;
- end else if (sw[1] | (tos_good[1] && ~sw[0])) begin
- tos_output = tos_inputs[1];
- leds[1] = 1;
- end else if (sw[0] | tos_good[0]) begin
- tos_output = tos_inputs[0];
- leds[0] = 1;
- end else
- tos_output = sw[3];
- leds[3] = tos_output;
+ cathode = data[7:0];
+ seg = data[9:8];
+ tos_select = data[11:10];
end
- TOS_Detect detect[2:0](.xtal(xtal), .tos_input(tos_inputs), .tos_good(tos_good));
+ 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: 50MHz (==20ns)
- * Minimum: 100ns (we'll allow 60ns for good measure)
- * 5 cycles (we'll allow 3 for good measure)
- * Maximum: 1000ns (we'll allow 1200ns for good measure)
- * 50 cycles (we'll allow 60 for good measure)
+
+/* 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,
tos_input_1a <= tos_input;
wire transition = tos_input ^ tos_input_1a;
- reg [5:0] lasttx = 0;
+ reg [3:0] lasttx = 0;
always @(posedge xtal) begin
if (transition) begin
- if (lasttx < 3) /* Too soon! */
+ if (lasttx < 2) /* Too soon! */
tos_good <= 0;
- else if (lasttx > 60) /* Too late! */
+ else if (lasttx > 30) /* Too late! */
tos_good <= 0;
else /* OK by me. */
tos_good <= 1;
lasttx <= 0;
end else begin
- if (lasttx != 63)
+ if (lasttx != 31)
lasttx <= lasttx + 1;
else
tos_good <= 0;
end
end
endmodule
+