Skip to content

Instantly share code, notes, and snippets.

@LispEngineer
Created August 8, 2023 01:18
Show Gist options
  • Save LispEngineer/95da27ead5474653c105bcafa328f491 to your computer and use it in GitHub Desktop.
Save LispEngineer/95da27ead5474653c105bcafa328f491 to your computer and use it in GitHub Desktop.
Digilent Basys3 7-segment driver in SystemVerilog
// Douglas P. Fields, Jr. 2023-08
// 7-segment hexadecimal driver for Digilent Basys3 board
`timescale 1ns / 1ps
module seven_segment (
input logic [3:0] num,
output logic [6:0] hex
);
// Purpose: Creates a case statement for all possible input binary numbers.
// Drives hex appropriately for each input combination.
always_comb
unique case (num)
4'b0000 : hex = 7'b011_1111; // 7E;
4'b0001 : hex = 7'b000_0110; // 30;
4'b0010 : hex = 7'b101_1011; // 6D;
4'b0011 : hex = 7'b100_1111; // 79;
4'b0100 : hex = 7'b110_0110; // 33;
4'b0101 : hex = 7'b110_1101; // 5B;
4'b0110 : hex = 7'b111_1101; // 5F;
4'b0111 : hex = 7'b000_0111; // 70;
4'b1000 : hex = 7'b111_1111; // 7F;
4'b1001 : hex = 7'b110_1111; // 7B;
4'b1010 : hex = 7'b111_0111; // 77;
4'b1011 : hex = 7'b111_1100; // 1F;
4'b1100 : hex = 7'b011_1001; // 4E;
4'b1101 : hex = 7'b101_1110; // 3D;
4'b1110 : hex = 7'b111_1001; // 4F;
4'b1111 : hex = 7'b111_0001; // 47;
endcase
endmodule: seven_segment
module multiplex_seg #(
// This works nicely with:
// 50_000_000 (ha)
// There is no visible ghosting in normal room lighting at:
// 50_000
// There is visible ghosting at: (regardless of using PULLTYPE PULLUP in XDC on cathodes or not)
// 5_000
// 1_000
// This fails miserably with:
// 10
CYCLES = 50_000 // Cannot be < 1
) (
input logic clk,
// 1 means light that segment
input logic [7:0] seg_in [4],
// 0 means light that segment when an is also 0
output logic [7:0] seg_out,
output logic [3:0] an
);
if (CYCLES < 1) begin
$error("CYCLES must be positive");
end
localparam CYCLE_BITS = $clog2(CYCLES);
// localparam CYCLE_BITS_HIGH = CYCLE_BITS - 1;
// localparam CYCLE_START_INT = CYCLES - 1;
localparam CYCLE_START = CYCLE_BITS'(CYCLES - 1);
logic [CYCLE_BITS-1:0] cycle = '0;
logic [1:0] digit = '0;
always_comb @(posedge clk) begin
if (cycle == '0) begin
cycle <= CYCLE_START;
digit <= digit + 1'd1;
an <= 4'b1111;
an[digit] <= 1'b0;
seg_out <= ~seg_in[digit];
end else begin
cycle <= cycle - 1'd1;
end
end
endmodule: multiplex_seg
module top (
input logic clk, // 100 MHz
input logic [15:0] sw,
input logic [4:0] btn,
output logic [15:0] led,
output logic [7:0] seg, // 7 segment displays; #7 is the decimal point
output logic [3:0] an // anodes for the 7 segment displays
);
logic [7:0] seg4 [4];
genvar i;
for (i = 0; i < 4; i++) begin
// Details on +:
// https://stackoverflow.com/questions/17778418/what-is-and
seven_segment hex_to_seg (.num(sw[(i * 4) +: 4]), .hex(seg4[i]));
end
assign led = sw;
multiplex_seg seg_display (
.clk(clk),
.seg_in(seg4),
.seg_out(seg),
.an(an)
);
endmodule: top
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment