`default_nettype none /////////////////////////////////////////////////////////////////////////////// // // 6.111 FPGA Labkit -- Template Toplevel Module // // For Labkit Revision 004 // Created: October 31, 2004, from revision 003 file // Author: Nathan Ickes, 6.111 staff // /////////////////////////////////////////////////////////////////////////////// module labkit_3_memory( // Remove comment from any signals you use in your design! // AC97 /* output wire beep, audio_reset_b, ac97_synch, ac97_sdata_out, input wire ac97_bit_clock, ac97_sdata_in, */ // VGA /* output wire [7:0] vga_out_red, vga_out_green, vga_out_blue, output wire vga_out_sync_b, vga_out_blank_b, vga_out_pixel_clock, vga_out_hsync, vga_out_vsync, */ // NTSC OUT /* output wire [9:0] tv_out_ycrcb, output wire tv_out_reset_b, tv_out_clock, tv_out_i2c_clock, tv_out_i2c_data, output wire tv_out_pal_ntsc, tv_out_hsync_b, tv_out_vsync_b, tv_out_blank_b, output wire tv_out_subcar_reset; */ // NTSC IN /* input wire [19:0] tv_in_ycrcb, input wire tv_in_data_valid, tv_in_line_clock1, tv_in_line_clock2, tv_in_aef, tv_in_hff, tv_in_aff, output wire tv_in_i2c_clock, tv_in_fifo_read, tv_in_fifo_clock, tv_in_iso, tv_in_reset_b, tv_in_clock, inout wire tv_in_i2c_data, */ // ZBT RAMS /* inout wire [35:0] ram0_data, output wire [18:0] ram0_address, output wire ram0_adv_ld, ram0_clk, ram0_cen_b, ram0_ce_b, ram0_oe_b, ram0_we_b, output wire [3:0] ram0_bwe_b, inout wire [35:0]ram1_data, output wire [18:0]ram1_address, output wire ram1_adv_ld, ram1_clk, ram1_cen_b, ram1_ce_b, ram1_oe_b, ram1_we_b, output wire [3:0] ram1_bwe_b, input wire clock_feedback_in, output wire clock_feedback_out, */ // FLASH /* inout wire [15:0] flash_data, output wire [23:0] flash_address, output wire flash_ce_b, flash_oe_b, flash_we_b, flash_reset_b, flash_byte_b, input wire flash_sts, */ // RS232 /* output wire rs232_txd, rs232_rts, input wire rs232_rxd, rs232_cts, */ // PS2 //input wire mouse_clock, mouse_data, //input wire keyboard_clock, keyboard_data, // FLUORESCENT DISPLAY output wire disp_blank, disp_clock, disp_rs, disp_ce_b, disp_reset_b, input wire disp_data_in, output wire disp_data_out, // SYSTEM ACE /* inout wire [15:0] systemace_data, output wire [6:0] systemace_address, output wire systemace_ce_b, systemace_we_b, systemace_oe_b, input wire systemace_irq, systemace_mpbrdy, */ // BUTTONS, SWITCHES, LEDS //input wire button0, //input wire button1, //input wire button2, //input wire button3, //input wire button_enter, //input wire button_right, //input wire button_left, input wire button_down, // input wire button_up, //input wire [7:0] switch, //output wire [7:0] led, // USER CONNECTORS, DAUGHTER CARD, LOGIC ANALYZER //inout wire [31:0] user1, //inout wire [31:0] user2, //inout wire [31:0] user3, inout wire [31:0] user4, //inout wire [43:0] daughtercard, //output wire [15:0] analyzer1_data, output wire analyzer1_clock, //output wire [15:0] analyzer2_data, output wire analyzer2_clock, //output wire [15:0] analyzer3_data, output wire analyzer3_clock, //output wire [15:0] analyzer4_data, output wire analyzer4_clock, // CLOCKS //input wire clock1, //input wire clock2, input wire clock_27mhz ); //////////////////////////////////////////////////////////////////////////// // // Reset Generation // // A shift register primitive is used to generate an active-high reset // signal that remains high for 16 clock cycles after configuration finishes // and the FPGA's internal clocks begin toggling. // //////////////////////////////////////////////////////////////////////////// wire reset_init; SRL16 reset_sr(.D(1'b0), .CLK(clock_27mhz), .Q(reset_init), .A0(1'b1), .A1(1'b1), .A2(1'b1), .A3(1'b1)); defparam reset_sr.INIT = 16'hFFFF; // debounce the down button for reset wire button_down_debounced; debounce db_down(0, clock_27mhz, button_down, button_down_debounced); // reset is the OR of button down and the FPGA reset wire reset = reset_init | ~button_down_debounced; wire [63:0] my_hex_data = {48'b0,4'd1,4'd2,4'd3,4'd4}; display_16hex disp(reset, clock_27mhz, my_hex_data, disp_blank, disp_clock, disp_rs, disp_ce_b, disp_reset_b, disp_data_out); endmodule /////////////////////////////////////////////////////////////////////////////// // // 6.111 FPGA Labkit -- Hex display driver // // File: display_16hex.v // Date: 24-Sep-05 // // Created: April 27, 2004 // Author: Nathan Ickes // // 24-Sep-05 Ike: updated to use new reset-once state machine, remove clear // 28-Nov-06 CJT: fixed race condition between CE and RS (thanks Javier!) // // This verilog module drives the labkit hex dot matrix displays, and puts // up 16 hexadecimal digits (8 bytes). These are passed to the module // through a 64 bit wire ("data"), asynchronously. // /////////////////////////////////////////////////////////////////////////////// module display_16hex (reset, clock_27mhz, data, disp_blank, disp_clock, disp_rs, disp_ce_b, disp_reset_b, disp_data_out); input reset, clock_27mhz; // clock and reset (active high reset) input [63:0] data; // 16 hex nibbles to display output disp_blank, disp_clock, disp_data_out, disp_rs, disp_ce_b, disp_reset_b; reg disp_data_out, disp_rs, disp_ce_b, disp_reset_b; //////////////////////////////////////////////////////////////////////////// // // Display Clock // // Generate a 500kHz clock for driving the displays. // //////////////////////////////////////////////////////////////////////////// reg [4:0] count; reg [7:0] reset_count; reg clock; wire dreset; always @(posedge clock_27mhz) begin if (reset) begin count = 0; clock = 0; end else if (count == 26) begin clock = ~clock; count = 5'h00; end else count = count+1; end always @(posedge clock_27mhz) if (reset) reset_count <= 100; else reset_count <= (reset_count==0) ? 0 : reset_count-1; assign dreset = (reset_count != 0); assign disp_clock = ~clock; //////////////////////////////////////////////////////////////////////////// // // Display State Machine // //////////////////////////////////////////////////////////////////////////// reg [7:0] state; // FSM state reg [9:0] dot_index; // index to current dot being clocked out reg [31:0] control; // control register reg [3:0] char_index; // index of current character reg [39:0] dots; // dots for a single digit reg [3:0] nibble; // hex nibble of current character assign disp_blank = 1'b0; // low <= not blanked always @(posedge clock) if (dreset) begin state <= 0; dot_index <= 0; control <= 32'h7F7F7F7F; end else casex (state) 8'h00: begin // Reset displays disp_data_out <= 1'b0; disp_rs <= 1'b0; // dot register disp_ce_b <= 1'b1; disp_reset_b <= 1'b0; dot_index <= 0; state <= state+1; end 8'h01: begin // End reset disp_reset_b <= 1'b1; state <= state+1; end 8'h02: begin // Initialize dot register (set all dots to zero) disp_ce_b <= 1'b0; disp_data_out <= 1'b0; // dot_index[0]; if (dot_index == 639) state <= state+1; else dot_index <= dot_index+1; end 8'h03: begin // Latch dot data disp_ce_b <= 1'b1; dot_index <= 31; // re-purpose to init ctrl reg disp_rs <= 1'b1; // Select the control register state <= state+1; end 8'h04: begin // Setup the control register disp_ce_b <= 1'b0; disp_data_out <= control[31]; control <= {control[30:0], 1'b0}; // shift left if (dot_index == 0) state <= state+1; else dot_index <= dot_index-1; end 8'h05: begin // Latch the control register data / dot data disp_ce_b <= 1'b1; dot_index <= 39; // init for single char char_index <= 15; // start with MS char state <= state+1; disp_rs <= 1'b0; // Select the dot register end 8'h06: begin // Load the user's dot data into the dot reg, char by char disp_ce_b <= 1'b0; disp_data_out <= dots[dot_index]; // dot data from msb if (dot_index == 0) if (char_index == 0) state <= 5; // all done, latch data else begin char_index <= char_index - 1; // goto next char dot_index <= 39; end else dot_index <= dot_index-1; // else loop thru all dots end endcase always @ (data or char_index) case (char_index) 4'h0: nibble <= data[3:0]; 4'h1: nibble <= data[7:4]; 4'h2: nibble <= data[11:8]; 4'h3: nibble <= data[15:12]; 4'h4: nibble <= data[19:16]; 4'h5: nibble <= data[23:20]; 4'h6: nibble <= data[27:24]; 4'h7: nibble <= data[31:28]; 4'h8: nibble <= data[35:32]; 4'h9: nibble <= data[39:36]; 4'hA: nibble <= data[43:40]; 4'hB: nibble <= data[47:44]; 4'hC: nibble <= data[51:48]; 4'hD: nibble <= data[55:52]; 4'hE: nibble <= data[59:56]; 4'hF: nibble <= data[63:60]; endcase always @(nibble) case (nibble) 4'h0: dots <= 40'b00111110_01010001_01001001_01000101_00111110; 4'h1: dots <= 40'b00000000_01000010_01111111_01000000_00000000; 4'h2: dots <= 40'b01100010_01010001_01001001_01001001_01000110; 4'h3: dots <= 40'b00100010_01000001_01001001_01001001_00110110; 4'h4: dots <= 40'b00011000_00010100_00010010_01111111_00010000; 4'h5: dots <= 40'b00100111_01000101_01000101_01000101_00111001; 4'h6: dots <= 40'b00111100_01001010_01001001_01001001_00110000; 4'h7: dots <= 40'b00000001_01110001_00001001_00000101_00000011; 4'h8: dots <= 40'b00110110_01001001_01001001_01001001_00110110; 4'h9: dots <= 40'b00000110_01001001_01001001_00101001_00011110; 4'hA: dots <= 40'b01111110_00001001_00001001_00001001_01111110; 4'hB: dots <= 40'b01111111_01001001_01001001_01001001_00110110; 4'hC: dots <= 40'b00111110_01000001_01000001_01000001_00100010; 4'hD: dots <= 40'b01111111_01000001_01000001_01000001_00111110; 4'hE: dots <= 40'b01111111_01001001_01001001_01001001_01000001; 4'hF: dots <= 40'b01111111_00001001_00001001_00001001_00000001; endcase endmodule // pulse synchronizer module synchronize #(parameter NSYNC = 2) // number of sync flops. must be >= 2 (input clk,in, output reg out); reg [NSYNC-2:0] sync; always @ (posedge clk) begin {out,sync} <= {sync[NSYNC-2:0],in}; end endmodule // Switch Debounce Module // use your system clock for the clock input // to produce a synchronous, debounced output module debounce #(parameter DELAY=270000) // .01 sec with a 27Mhz clock (input reset, clock, noisy, output reg clean); reg [18:0] count; reg new; always @(posedge clock) if (reset) begin count <= 0; new <= noisy; clean <= noisy; end else if (noisy != new) begin new <= noisy; count <= 0; end else if (count == DELAY) clean <= new; else count <= count+1; endmodule