de2lab2c.v
module de2lab2c( // Clock Input (50 MHz) input CLOCK_50, // Push Buttons input [3:0] KEY, // DPDT Switches input [17:0] SW, // 7-SEG Displays output [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6, HEX7, // LEDs output [8:0] LEDG, // LED Green[8:0] output [17:0] LEDR, // LED Red[17:0] // PS2 data and clock lines inout PS2_DAT, inout PS2_CLK, // GPIO Connections inout [35:0] GPIO_0, GPIO_1 ); // set all inout ports to tri-state assign GPIO_0 = 36'hzzzzzzzzz; assign GPIO_1 = 36'hzzzzzzzzz; wire RST; assign RST = KEY[0]; // Connect dip switches to red LEDs assign LEDR[17:0] = SW[17:0]; // turn off green LEDs //assign LEDG = 0; wire reset = 1'b0; wire [7:0] scan_code; reg [7:0] history[1:4]; wire read, scan_ready; one_pulse oneshot1(read,scan_ready,CLOCK_50); ps2_rcv rcv( .ps2_clk(PS2_CLK), .ps2_data(PS2_DAT), .clock50(CLOCK_50), .reset(reset), .read_ack(read), .write_ack(write_ack), .data_ready(scan_ready), .data(scan_code) ); hex_7seg dsp0(history[1][3:0],HEX0); hex_7seg dsp1(history[1][7:4],HEX1); hex_7seg dsp2(history[2][3:0],HEX2); hex_7seg dsp3(history[2][7:4],HEX3); hex_7seg dsp4(history[3][3:0],HEX4); hex_7seg dsp5(history[3][7:4],HEX5); hex_7seg dsp6(history[4][3:0],HEX6); hex_7seg dsp7(history[4][7:4],HEX7); always @(posedge scan_ready, negedge RST) if (!RST) begin history[4] <= 4'h0; history[3] <= 4'h0; history[2] <= 4'h0; history[1] <= 4'h0; end else begin history[4] <= history[3]; history[3] <= history[2]; history[2] <= history[1]; history[1] <= scan_code; end // blank remaining digits /* wire [6:0] blank = 7'b111_1111; assign HEX2 = blank; assign HEX3 = blank; assign HEX4 = blank; assign HEX5 = blank; assign HEX6 = blank; assign HEX7 = blank; */ reg start; reg [7:0] command; wire write_ack, wait_ack, timeout_error; wire cmd1, cmd2, cmd3; assign LEDG[2] = start; assign LEDG[1] = wait_ack; assign LEDG[0] = timeout_error; ps2_xmt xmt( .clock50(CLOCK_50), .nRESET(RST), .command(command), .start(start), .wait_ack(wait_ack), .write_ack(write_ack), .timeout_error(timeout_error), .ps2_data(PS2_DAT), .ps2_clock(PS2_CLK) ); reg [3:0] ir; reg [3:0] pc; wire xmt_complete = (wait_ack && scan_ready); one_pulse oneshot2(cmd1,~KEY[3],CLOCK_50); one_pulse oneshot3(cmd2,~KEY[2],CLOCK_50); one_pulse oneshot4(cmd3,~KEY[1],CLOCK_50); wire [3:0] npc = pc + 1'b1; wire [1:0] opcode = ir[3:2]; always @(posedge CLOCK_50, negedge RST) if (!RST) pc <= 3'b000; else case (opcode) 2'h1: begin start <= 1'b1; command <= data; pc <= npc; end 2'h2: if (xmt_complete) begin start <= 1'b0; pc <= npc; end default: begin start <= 1'b0; if (cmd1) pc <= 4'h1; else if (cmd2) pc <= 4'h4; else if (cmd3) pc <= 4'h7; end endcase assign LEDG[7:4] = pc; always case (pc) 4'h0: ir = 4'b0000; // halt 4'h1: ir = 4'b0101; // write 1 (FF) 4'h2: ir = 4'b1000; // wait (for acknowledgement signal) 4'h3: ir = 4'b0000; // halt 4'h4: ir = 4'b0110; // write 2 (E9) 4'h5: ir = 4'b1000; // wait 4'h6: ir = 4'b0000; // halt 4'h7: ir = 4'b0111; // write 3 (EB) 4'h8: ir = 4'b1000; // wait 4'h9: ir = 4'b0000; // halt default: ir = 4'b0000; // halt endcase reg [7:0] data; always case (ir[1:0]) 2'b01: data <= 8'hFF; 2'b10: data <= 8'hE9; 2'b11: data <= 8'hEB; default: data <= 8'h00; endcase endmodule
hex_7seg.v
module hex_7seg(hex_digit,seg); input [3:0] hex_digit; output [6:0] seg; reg [6:0] seg; // seg = {g,f,e,d,c,b,a}; // 0 is on and 1 is off always @ (hex_digit) case (hex_digit) 4'h0: seg = 7'b1000000; 4'h1: seg = 7'b1111001; // ---a---- 4'h2: seg = 7'b0100100; // | | 4'h3: seg = 7'b0110000; // f b 4'h4: seg = 7'b0011001; // | | 4'h5: seg = 7'b0010010; // ---g---- 4'h6: seg = 7'b0000010; // | | 4'h7: seg = 7'b1111000; // e c 4'h8: seg = 7'b0000000; // | | 4'h9: seg = 7'b0011000; // ---d---- 4'ha: seg = 7'b0001000; 4'hb: seg = 7'b0000011; 4'hc: seg = 7'b1000110; 4'hd: seg = 7'b0100001; 4'he: seg = 7'b0000110; 4'hf: seg = 7'b0001110; endcase endmodule
one_pulse.v
module one_pulse(pulse_out,trigger_in, clk); input trigger_in,clk; output pulse_out; reg pulse_out, delay; always @ (posedge clk) begin if (trigger_in && !delay) pulse_out <= 1'b1; else pulse_out <= 1'b0; delay <= trigger_in; end endmodule
ps2_rcv.v
module ps2_rcv(ps2_clk, ps2_data, clock50, reset, read_ack, write_ack, data_ready, data); input ps2_clk; input ps2_data; input clock50; // 50 Mhz system clock input reset; input read_ack, write_ack; output data_ready; output [7:0] data; reg ready_set; reg [7:0] data; reg data_ready; reg read_char; reg clock; // 25 Mhz internal clock reg [3:0] incnt; reg [8:0] shiftin; reg [7:0] filter; reg ps2_clk_filtered; // data_ready is set to 1 when data is available. // user should set read_ack to 1 and then to 0 to clear data_ready always @ (posedge ready_set or posedge read_ack) if (read_ack) data_ready <= 1'b0; else data_ready <= 1'b1; // divide-by-two 50MHz to 25MHz always @(posedge clock50) clock <= ~clock; // This process filters the raw clock signal coming from the ps2 // using an eight-bit shift register and two AND gates always @(posedge clock) begin filter <= {ps2_clk, filter[7:1]}; if (filter==8'b1111_1111) ps2_clk_filtered <= 1; else if (filter==8'b0000_0000) ps2_clk_filtered <= 0; end // This process reads in serial data coming from the terminal always @(posedge ps2_clk_filtered) begin if (reset==1) begin incnt <= 4'b0000; read_char <= 0; end else if (!ps2_data && (!read_char || write_ack)) // this is either start bit or write acknowledgement bit begin if (!write_ack) read_char <= 1; ready_set <= 0; end else begin // shift in next 8 data bits to assemble a data code if (read_char == 1) begin if (incnt < 9) begin incnt <= incnt + 1'b1; shiftin = { ps2_data, shiftin[8:1]}; ready_set <= 0; end else begin incnt <= 0; data <= shiftin[7:0]; read_char <= 0; ready_set <= 1; end end end end endmodule
ps2_xmt.v
module ps2_xmt(input clock50, input nRESET, input [7:0] command, input start, inout ps2_data, inout ps2_clock, output reg write_ack, output wait_ack, output timeout_error); reg [7:0] filter; reg clock25; reg clock_posedge, filtered_clock; // generate 25MHz clock from 50MHz clock always @(posedge clock50) clock25 = ~clock25; // Filter the PS2_clock signal always @(posedge clock25) begin filter <= {filter[6:0],ps2_clock}; if (filter==8'hff) begin clock_posedge <= (filtered_clock==1'b0); filtered_clock <= 1'b1; end if (filter==8'h00) begin //clock_negedge = (filtered_clock==1'b1); filtered_clock <= 1'b0; end end reg [19:0] counter; reg [2:0] state; parameter WAIT_INIT = 2500, // 100 us (2500/25MHz) WAIT_TIMEOUT = 750000; // 30 ms parameter IDLE = 3'h0, INIT = 3'h1, WAIT_FOR_CLOCK = 3'h2, TRANSMIT = 3'h3, WAIT_ACK = 3'h4, TIMEOUT = 3'h5; always @(posedge clock25) begin if (!nRESET || state==IDLE) counter = 20'h00000; else counter <= counter + 1'b1; end always @(posedge clock25) if (!nRESET) state <= IDLE; else case (state) IDLE: state <= (start? INIT: IDLE); INIT: if (counter==WAIT_INIT) state <= WAIT_FOR_CLOCK; WAIT_FOR_CLOCK: if (clock_posedge) state <= TRANSMIT; else if (counter>=WAIT_TIMEOUT) state <= TIMEOUT; TRANSMIT: if (write_ack) state <= WAIT_ACK; else if (counter>=WAIT_TIMEOUT) state <= TIMEOUT; WAIT_ACK: if (!start) state <= IDLE; TIMEOUT: state <= (!start? IDLE: TIMEOUT); default: state <= IDLE; endcase wire parity = ~(^command); reg [9:0] bits; reg [3:0] bitcount; always @ (negedge filtered_clock) if (state==TRANSMIT) begin if (bitcount<=4'b1001) begin bitcount <= bitcount + 1'b1; bits <= {1'b1, bits[9:1]}; end else write_ack <= 1'b1; end else begin bits <= {parity,command,1'b0}; bitcount <= 4'h0; write_ack <= 1'b0; end assign ps2_clock = (state==INIT? 1'b0: 1'bz); assign ps2_data = (state==WAIT_FOR_CLOCK? 1'b0: (state==TRANSMIT? bits[0]: 1'bz)); assign wait_ack = (state==WAIT_ACK); assign timeout_error = (state==TIMEOUT); endmodule
fit.summary
Fitter Status : Successful - Tue Jun 12 13:19:15 2007 Quartus II Version : 6.0 Build 178 04/27/2006 SJ Full Version Revision Name : de2lab2c Top-level Entity Name : de2lab2c Family : Cyclone II Device : EP2C35F672C6 Timing Models : Final Total logic elements : 188 / 33,216 ( < 1 % ) Total registers : 125 Total pins : 180 / 475 ( 38 % ) Total virtual pins : 0 Total memory bits : 0 / 483,840 ( 0 % ) Embedded Multiplier 9-bit elements : 0 / 70 ( 0 % ) Total PLLs : 0 / 4 ( 0 % )
tan.summary
-------------------------------------------------------------------------------------- Timing Analyzer Summary -------------------------------------------------------------------------------------- Type : Worst-case tsu Slack : N/A Required Time : None Actual Time : 6.063 ns From : KEY[0] To : command[4] From Clock : -- To Clock : CLOCK_50 Failed Paths : 0 Type : Worst-case tco Slack : N/A Required Time : None Actual Time : 21.576 ns From : history[1][4] To : HEX1[2] From Clock : CLOCK_50 To Clock : -- Failed Paths : 0 Type : Worst-case tpd Slack : N/A Required Time : None Actual Time : 9.804 ns From : SW[16] To : LEDR[16] From Clock : -- To Clock : -- Failed Paths : 0 Type : Worst-case th Slack : N/A Required Time : None Actual Time : 1.029 ns From : PS2_DAT To : ps2_rcv:rcv|ready_set From Clock : -- To Clock : CLOCK_50 Failed Paths : 0 Type : Clock Setup: 'CLOCK_50' Slack : N/A Required Time : None Actual Time : 90.68 MHz ( period = 11.028 ns ) From : ps2_xmt:xmt|write_ack To : ps2_xmt:xmt|state.TRANSMIT From Clock : CLOCK_50 To Clock : CLOCK_50 Failed Paths : 0 Type : Clock Hold: 'CLOCK_50' Slack : Not operational: Clock Skew > Data Delay Required Time : None Actual Time : N/A From : command[4] To : ps2_xmt:xmt|bits[3] From Clock : CLOCK_50 To Clock : CLOCK_50 Failed Paths : 37 Type : Total number of failed paths Slack : Required Time : Actual Time : From : To : From Clock : To Clock : Failed Paths : 37 --------------------------------------------------------------------------------------
Maintained by John Loomis, last updated Tue Jun 12 13:25:36 2007