`default_nettype none /////////////////////////////////////////////////////////////////////////////// // // 6.111 FPGA Labkit -- Lab 1 Template // // Commented out unused signals to remove confusing diagnostic messages. // 2/2009 GPH - not compatible with ISE 10 // Created: January 12, 2006 // Author: Nathan Ickes (orginal labkit template and display module) // Additional changes made by Kyeong-Jae Lee // // Purpose: Provides a template for a simple 7-segment display driver using // the labkit's slide switches and the LED dot-matrix display. // // Usage: Implement your own 7-segment decoder ('segment_decoder'). // Use switch[3:0] as the 4-bit input, and the LED display should show the // correct digit. // // Structure: // lab1 : top-level labkit module // display : driver for labkit's LED display // dot_converter : conversion module for 7-segment to LED dot-matrix // segment_decoder : conversion module for 4-bit input to 7-segment display (NOT INCLUDED) // /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // // 6.111 FPGA Labkit -- Template Toplevel Module // // For Labkit Revision 004 // // // Created: October 31, 2004, from revision 003 file // Author: Nathan Ickes // /////////////////////////////////////////////////////////////////////////////// // // CHANGES FOR BOARD REVISION 004 // // 1) Added signals for logic analyzer pods 2-4. // 2) Expanded "tv_in_ycrcb" to 20 bits. // 3) Renamed "tv_out_data" to "tv_out_i2c_data" and "tv_out_sclk" to // "tv_out_i2c_clock". // 4) Reversed disp_data_in and disp_data_out signals, so that "out" is an // output of the FPGA, and "in" is an input. // // CHANGES FOR BOARD REVISION 003 // // 1) Combined flash chip enables into a single signal, flash_ce_b. // // CHANGES FOR BOARD REVISION 002 // // 1) Added SRAM clock feedback path input and output // 2) Renamed "mousedata" to "mouse_data" // 3) Renamed some ZBT memory signals. Parity bits are now incorporated into // the data bus, and the byte write enables have been combined into the // 4-bit ram#_bwe_b bus. // 4) Removed the "systemace_clock" net, since the SystemACE clock is now // hardwired on the PCB to the oscillator. // /////////////////////////////////////////////////////////////////////////////// // // Complete change history (including bug fixes) // // 2005-Sep-09: Added missing default assignments to "ac97_sdata_out", // "disp_data_out", "analyzer[2-3]_clock" and // "analyzer[2-3]_data". // // 2005-Jan-23: Reduced flash address bus to 24 bits, to match 128Mb devices // actually populated on the boards. (The boards support up to // 256Mb devices, with 25 address lines.) // // 2004-Oct-31: Adapted to new revision 004 board. // // 2004-May-01: Changed "disp_data_in" to be an output, and gave it a default // value. (Previous versions of this file declared this port to // be an input.) // // 2004-Apr-29: Reduced SRAM address busses to 19 bits, to match 18Mb devices // actually populated on the boards. (The boards support up to // 72Mb devices, with 21 address lines.) // // 2004-Apr-29: Change history started // /////////////////////////////////////////////////////////////////////////////// module lab1_labkit( // 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; SRL16 reset_sr(.D(1'b0), .CLK(clock_27mhz), .Q(reset), .A0(1'b1), .A1(1'b1), .A2(1'b1), .A3(1'b1)); defparam reset_sr.INIT = 16'hFFFF; //////////////////////////////////////////////////////////////// // DIGIT DISPLAY MODULES //////////////////////////////////////////////////////////////// wire [639:0] dots; wire [39:0] digit_dots; wire a,b,c,d,e,f,g; // wire disp_blank, disp_clock, disp_rs, disp_ce_b, disp_reset_b, disp_data_out; //Converts 4-bit input to 7-segment segment_decoder dec(switch[3:0], a,b,c,d,e,f,g); //Converts 7-segment display into LED dot matrix // (instead of driving a 7-segment through I/O pins, // each segment is displayed using the Labkit's LED display) dot_converter cnv(a,b,c,d,e,f,g, digit_dots); //Driver for LED Display display disp(1'b0, clock_27mhz, disp_blank, disp_clock, disp_rs, disp_ce_b, disp_reset_b, disp_data_out, dots); assign dots = {600'd0, digit_dots}; assign led = ~{4'h0, switch[3:0]}; endmodule /////////////////////////////////////////////////////////////////////////////// // // 7-SEGMENT - DOT CONVERTER // 6.111 (Spring 2006) // Created: January 5, 2006 // Author: Kyeong-Jae Lee // // Note: Instead of driving a 7-segment through the I/O pins, // each segment is modeled and displayed using the Labkit's LED dot-matrix /////////////////////////////////////////////////////////////////////////////// module dot_converter(a,b,c,d,e,f,g, dot_driver); input a,b,c,d,e,f,g; // 7-segment drivers output [39:0] dot_driver; //drives dot_matrix display //mask bits for each segment wire [39:0] mask_null = 40'h00_0000_0000; wire [39:0] mask_a = 40'b00000001_00000001_00000001_00000001_00000001; wire [39:0] mask_b = 40'b00000000_00000000_00000000_00000000_00001111; wire [39:0] mask_c = 40'b00000000_00000000_00000000_00000000_01111000; wire [39:0] mask_d = 40'b01000000_01000000_01000000_01000000_01000000; wire [39:0] mask_e = 40'b01111000_00000000_00000000_00000000_00000000; wire [39:0] mask_f = 40'b00001111_00000000_00000000_00000000_00000000; wire [39:0] mask_g = 40'b00001000_00001000_00001000_00001000_00001000; wire [39:0] dot_a = a ? mask_a : mask_null; wire [39:0] dot_b = b ? mask_b : mask_null; wire [39:0] dot_c = c ? mask_c : mask_null; wire [39:0] dot_d = d ? mask_d : mask_null; wire [39:0] dot_e = e ? mask_e : mask_null; wire [39:0] dot_f = f ? mask_f : mask_null; wire [39:0] dot_g = g ? mask_g : mask_null; //Combinatorially assign individual segments assign dot_driver = dot_a | dot_b | dot_c | dot_d | dot_e | dot_f | dot_g; endmodule /////////////////////////////////////////////////////////////////////////////// // // 6.111 FPGA Labkit -- Alphanumeric Display Interface // // // Created: November 5, 2003 // Author: Nathan Ickes // /////////////////////////////////////////////////////////////////////////////// // // Change history // // 2005-05-09: Made input registered, and converted the 640-input MUX // to a 640-bit shift register. // /////////////////////////////////////////////////////////////////////////////// module display (reset, clock_27mhz, disp_blank, disp_clock, disp_rs, disp_ce_b, disp_reset_b, disp_data_out, dots); input reset, clock_27mhz; output disp_blank, disp_clock, disp_data_out, disp_rs, disp_ce_b, disp_reset_b; input [639:0] dots; 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; reg [9:0] dot_index; reg [31:0] control; reg [639:0] ldots; 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 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_rs <= 1'b1; // Select the control register disp_ce_b <= 1'b1; dot_index <= 31; 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}; if (dot_index == 0) state <= state+1; else dot_index <= dot_index-1; end 8'h05: begin // Latch the control register data disp_rs <= 1'b0; // Select the dot register disp_ce_b <= 1'b1; dot_index <= 639; ldots <= dots; state <= state+1; end 8'h06: begin // Load the user's dot data into the dot register disp_ce_b <= 1'b0; disp_data_out <= ldots[639]; ldots <= ldots<<1; if (dot_index == 0) state <= 5; else dot_index <= dot_index-1; end endcase endmodule