`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // // Create Date: 10/1/2015 V1.0 // Design Name: display characters. Left, right, up, down moves the text // Based on cstringdisp.v // Module Name: labkit // ////////////////////////////////////////////////////////////////////////////////// module labkit( input clk_100mhz, input[15:0] sw, input btnc, btnu, btnl, btnr, btnd, output logic[3:0] vga_r, output logic[3:0] vga_b, output logic[3:0] vga_g, output logic vga_hs, output logic vga_vs, output logic led16_b, led16_g, led16_r, output logic led17_b, led17_g, led17_r, output logic [15:0] led, output logic ca, cb, cc, cd, ce, cf, cg, dp, // segments a-g, dp output logic[7:0] an // Display location 0-7 ); // create 65mhz system clock, happens to match 1024 x 768 XVGA timing clk_wiz_lab3 clkdivider(.clk_in1(clk_100mhz), .clk_out1(clk_65mhz)); logic [31:0] data; // instantiate 7-segment display; display (8) 4-bit hex logic [6:0] segments; assign {cg, cf, ce, cd, cc, cb, ca} = segments[6:0]; display_8hex display(.clk_in(clk_65mhz),.data_in(data), .seg_out(segments), .strobe_out(an)); //assign seg[6:0] = segments; assign dp = 1'b1; // turn off the period assign led = sw; // turn leds on assign data = {28'h0123456, sw[3:0]}; // display 0123456 + sw[3:0] assign led16_r = btnl; // left button -> red led assign led16_g = btnc; // center button -> green led assign led16_b = btnr; // right button -> blue led assign led17_r = btnl; assign led17_g = btnc; assign led17_b = btnr; logic [10:0] hcount; // pixel on current line logic [9:0] vcount; // line number logic hsync, vsync; logic [11:0] pixel; logic [11:0] rgb; // UP and DOWN buttons for pong paddle logic up,down; debounce db2(.reset_in(reset),.clock_in(clk_65mhz),.noisy_in(btnu),.clean_out(up)); debounce db3(.reset_in(reset),.clock_in(clk_65mhz),.noisy_in(btnd),.clean_out(down)); debounce db4(.reset_in(reset),.clock_in(clk_65mhz),.noisy_in(btnl),.clean_out(left)); debounce db5(.reset_in(reset),.clock_in(clk_65mhz),.noisy_in(btnr),.clean_out(right)); xvga xvga1(.vclock_in(clk_65mhz),.hcount_out(hcount),.vcount_out(vcount), .hsync_out(hsync),.vsync_out(vsync),.blank_out(blank)); // character display module: sample string in middle of screen wire [63:0] cstring = "12345678"; wire [2:0] cdpixel; char_string_display cdisplay(.vclock(clk_65mhz), .hcount(hcount), .vcount(vcount), .pixel(cdpixel),.cstring(cstring), .cx(11'd512), .cy(10'd384)); // character display module: moving text wire [18*8-1:0] cstring2 = " 6.111 is Awesome!"; wire [2:0] cdpixel2; reg [10:0] cx2; reg [9:0] cy2; char_string_display cd2(clk_65mhz, hcount,vcount,cdpixel2,cstring2,cx2,cy2); defparam cd2.NCHAR = 18; defparam cd2.NCHAR_BITS = 5; // text movement parameter PADMOVERATE = 060000; reg [31:0] pcount; wire padflag = (pcount == PADMOVERATE) ? 1 : 0; always @(posedge clk_65mhz) begin pcount <= reset ? 0 : (padflag ? 0 : pcount + 1); cy2 <= reset ? 0 : (up & padflag) ? (cy2>0 ? cy2-1 : cy2) : ((down & padflag) ? (cy2+24<767 ? cy2+1 : cy2) : cy2); cx2 <= reset ? 0 : (left & padflag) ? (cx2>0 ? cx2-1 : cx2) : ((right & padflag) ? (cx2+16*12<1024 ? cx2+1 : cx2) : cx2); end // btnc button is user reset logic reset; debounce db1(.reset_in(reset),.clock_in(clk_65mhz),.noisy_in(btnc),.clean_out(reset)); logic phsync,pvsync,pblank; pong_game pg(.vclock_in(clk_65mhz),.reset_in(reset), .cpixel(cdpixel|cdpixel2), .up_in(up),.down_in(down),.pspeed_in(sw[15:12]), .hcount_in(hcount),.vcount_in(vcount), .hsync_in(hsync),.vsync_in(vsync),.blank_in(blank), .phsync_out(phsync),.pvsync_out(pvsync),.pblank_out(pblank),.pixel_out(pixel)); logic border = (hcount==0 | hcount==1023 | vcount==0 | vcount==767 | hcount == 512 | vcount == 384); logic b,hs,vs; always_ff @(posedge clk_65mhz) begin if (sw[1:0] == 2'b01) begin // 1 pixel outline of visible area (white) hs <= hsync; vs <= vsync; b <= blank; rgb <= {12{border}}; end else if (sw[1:0] == 2'b10) begin // color bars hs <= hsync; vs <= vsync; b <= blank; rgb <= {{4{hcount[8]}}, {4{hcount[7]}}, {4{hcount[6]}}} ; end else begin // default: pong hs <= phsync; vs <= pvsync; b <= pblank; rgb <=pixel; end end // assign rgb = sw[0] ? {12{border}} : pixel ; //{{4{hcount[7]}}, {4{hcount[6]}}, {4{hcount[5]}}}; // the following lines are required for the Nexys4 VGA circuit - do not change assign vga_r = ~b ? rgb[11:8]: 0; assign vga_g = ~b ? rgb[7:4] : 0; assign vga_b = ~b ? rgb[3:0] : 0; assign vga_hs = ~hs; assign vga_vs = ~vs; endmodule //////////////////////////////////////////////////////////////////////////////// // // pong_game: modified to show character string // //////////////////////////////////////////////////////////////////////////////// module pong_game ( input vclock_in, // 65MHz clock input [2:0] cpixel, // pixels for cstring input reset_in, // 1 to initialize module input up_in, // 1 when paddle should move up input down_in, // 1 when paddle should move down input [3:0] pspeed_in, // puck speed in pixels/tick input [10:0] hcount_in, // horizontal index of current pixel (0..1023) input [9:0] vcount_in, // vertical index of current pixel (0..767) input hsync_in, // XVGA horizontal sync signal (active low) input vsync_in, // XVGA vertical sync signal (active low) input blank_in, // XVGA blanking (1 means output black pixel) output logic phsync_out, // pong game's horizontal sync output logic pvsync_out, // pong game's vertical sync output logic pblank_out, // pong game's blanking output logic [11:0] pixel_out // pong game's pixel // r=11:8, g=7:4, b=3:0 ); logic [2:0] checkerboard; // REPLACE ME! The code below just generates a color checkerboard // using 64 pixel by 64 pixel squares. assign phsync_out = hsync_in; assign pvsync_out = vsync_in; assign pblank_out = blank_in; // assign checkerboard = hcount_in[8:6] + vcount_in[8:6]; // here we use three bits from hcount and vcount to generate the // checkerboard // assign pixel_out = {{4{checkerboard[2]}}, {4{checkerboard[1]}}, {4{checkerboard[0]}}} ; assign pixel_out = {{4{cpixel[2]}}, {4{cpixel[1]}}, {4{cpixel[0]}}} ; endmodule module synchronize #(parameter NSYNC = 3) // number of sync flops. must be >= 2 (input clk,in, output logic out); logic [NSYNC-2:0] sync; always_ff @ (posedge clk) begin {out,sync} <= {sync[NSYNC-2:0],in}; end endmodule /////////////////////////////////////////////////////////////////////////////// // // Pushbutton Debounce Module (video version - 24 bits) // /////////////////////////////////////////////////////////////////////////////// module debounce (input reset_in, clock_in, noisy_in, output logic clean_out); logic [19:0] count; logic new_input; always_ff @(posedge clock_in) if (reset_in) begin new_input <= noisy_in; clean_out <= noisy_in; count <= 0; end else if (noisy_in != new_input) begin new_input<=noisy_in; count <= 0; end else if (count == 1000000) clean_out <= new_input; else count <= count+1; endmodule ////////////////////////////////////////////////////////////////////////////////// // Engineer: g.p.hom // // Create Date: 18:18:59 04/21/2013 // Module Name: display_8hex // Description: Display 8 hex numbers on 7 segment display // ////////////////////////////////////////////////////////////////////////////////// module display_8hex( input clk_in, // system clock input [31:0] data_in, // 8 hex numbers, msb first output logic [6:0] seg_out, // seven segment display output output logic [7:0] strobe_out // digit strobe ); localparam bits = 13; logic [bits:0] counter = 0; // clear on power up logic [6:0] segments[15:0]; // 16 7 bit memorys assign segments[0] = 7'b100_0000; // inverted logic assign segments[1] = 7'b111_1001; // gfedcba assign segments[2] = 7'b010_0100; assign segments[3] = 7'b011_0000; assign segments[4] = 7'b001_1001; assign segments[5] = 7'b001_0010; assign segments[6] = 7'b000_0010; assign segments[7] = 7'b111_1000; assign segments[8] = 7'b000_0000; assign segments[9] = 7'b001_1000; assign segments[10] = 7'b000_1000; assign segments[11] = 7'b000_0011; assign segments[12] = 7'b010_0111; assign segments[13] = 7'b010_0001; assign segments[14] = 7'b000_0110; assign segments[15] = 7'b000_1110; always_ff @(posedge clk_in) begin // Here I am using a counter and select 3 bits which provides // a reasonable refresh rate starting the left most digit // and moving left. counter <= counter + 1; case (counter[bits:bits-2]) 3'b000: begin // use the MSB 4 bits seg_out <= segments[data_in[31:28]]; strobe_out <= 8'b0111_1111 ; end 3'b001: begin seg_out <= segments[data_in[27:24]]; strobe_out <= 8'b1011_1111 ; end 3'b010: begin seg_out <= segments[data_in[23:20]]; strobe_out <= 8'b1101_1111 ; end 3'b011: begin seg_out <= segments[data_in[19:16]]; strobe_out <= 8'b1110_1111; end 3'b100: begin seg_out <= segments[data_in[15:12]]; strobe_out <= 8'b1111_0111; end 3'b101: begin seg_out <= segments[data_in[11:8]]; strobe_out <= 8'b1111_1011; end 3'b110: begin seg_out <= segments[data_in[7:4]]; strobe_out <= 8'b1111_1101; end 3'b111: begin seg_out <= segments[data_in[3:0]]; strobe_out <= 8'b1111_1110; end endcase end endmodule ////////////////////////////////////////////////////////////////////////////////// // Update: 8/8/2019 GH // Create Date: 10/02/2015 02:05:19 AM // Module Name: xvga // // xvga: Generate VGA display signals (1024 x 768 @ 60Hz) // // ---- HORIZONTAL ----- ------VERTICAL ----- // Active Active // Freq Video FP Sync BP Video FP Sync BP // 640x480, 60Hz 25.175 640 16 96 48 480 11 2 31 // 800x600, 60Hz 40.000 800 40 128 88 600 1 4 23 // 1024x768, 60Hz 65.000 1024 24 136 160 768 3 6 29 // 1280x1024, 60Hz 108.00 1280 48 112 248 768 1 3 38 // 1280x720p 60Hz 75.25 1280 72 80 216 720 3 5 30 // 1920x1080 60Hz 148.5 1920 88 44 148 1080 4 5 36 // // change the clock frequency, front porches, sync's, and back porches to create // other screen resolutions //////////////////////////////////////////////////////////////////////////////// module xvga(input vclock_in, output logic [10:0] hcount_out, // pixel number on current line output logic [9:0] vcount_out, // line number output logic vsync_out, hsync_out, output logic blank_out); parameter DISPLAY_WIDTH = 1024; // display width parameter DISPLAY_HEIGHT = 768; // number of lines parameter H_FP = 24; // horizontal front porch parameter H_SYNC_PULSE = 136; // horizontal sync parameter H_BP = 160; // horizontal back porch parameter V_FP = 3; // vertical front porch parameter V_SYNC_PULSE = 6; // vertical sync parameter V_BP = 29; // vertical back porch // horizontal: 1344 pixels total // display 1024 pixels per line logic hblank,vblank; logic hsyncon,hsyncoff,hreset,hblankon; assign hblankon = (hcount_out == (DISPLAY_WIDTH -1)); assign hsyncon = (hcount_out == (DISPLAY_WIDTH + H_FP - 1)); //1047 assign hsyncoff = (hcount_out == (DISPLAY_WIDTH + H_FP + H_SYNC_PULSE - 1)); // 1183 assign hreset = (hcount_out == (DISPLAY_WIDTH + H_FP + H_SYNC_PULSE + H_BP - 1)); //1343 // vertical: 806 lines total // display 768 lines logic vsyncon,vsyncoff,vreset,vblankon; assign vblankon = hreset & (vcount_out == (DISPLAY_HEIGHT - 1)); // 767 assign vsyncon = hreset & (vcount_out == (DISPLAY_HEIGHT + V_FP - 1)); // 771 assign vsyncoff = hreset & (vcount_out == (DISPLAY_HEIGHT + V_FP + V_SYNC_PULSE - 1)); // 777 assign vreset = hreset & (vcount_out == (DISPLAY_HEIGHT + V_FP + V_SYNC_PULSE + V_BP - 1)); // 805 // sync and blanking logic next_hblank,next_vblank; assign next_hblank = hreset ? 0 : hblankon ? 1 : hblank; assign next_vblank = vreset ? 0 : vblankon ? 1 : vblank; always_ff @(posedge vclock_in) begin hcount_out <= hreset ? 0 : hcount_out + 1; hblank <= next_hblank; hsync_out <= hsyncon ? 0 : hsyncoff ? 1 : hsync_out; // active low vcount_out <= hreset ? (vreset ? 0 : vcount_out + 1) : vcount_out; vblank <= next_vblank; vsync_out <= vsyncon ? 0 : vsyncoff ? 1 : vsync_out; // active low blank_out <= next_vblank | (next_hblank & ~hreset); end endmodule