Skip to content

Instantly share code, notes, and snippets.

@bdm-k
Last active October 24, 2023 06:03
Show Gist options
  • Save bdm-k/8fa1ed190439622e83021a7d8b3c7d4f to your computer and use it in GitHub Desktop.
Save bdm-k/8fa1ed190439622e83021a7d8b3c7d4f to your computer and use it in GitHub Desktop.
A SystemVerilog module that displays byte data with 7 segment displays.
module byte_display(
input logic clk, rstn,
input logic [7:0] data,
output logic [6:0] segment, // = {CA, CB, CC, CD, CE, CF, CG}
output logic [1:0] digit_en // = {AN[1], AN[0]}
);
localparam CLK_CNT_LIMIT = 65536 - 1; // 2^16 - 1
function [6:0] to_segment(
input logic [3:0] a
);
to_segment = {
a == 4'h0 | a == 4'h2 | a == 4'h3 | a == 4'h5 | a == 4'h6 |
a == 4'h7 | a == 4'h8 | a == 4'h9 | a == 4'hA | a == 4'hE |
a == 4'hF,
a == 4'h0 | a == 4'h1 | a == 4'h2 | a == 4'h3 | a == 4'h4 |
a == 4'h7 | a == 4'h8 | a == 4'h9 | a == 4'hA | a == 4'hD,
a == 4'h0 | a == 4'h1 | a == 4'h3 | a == 4'h4 | a == 4'h5 |
a == 4'h6 | a == 4'h7 | a == 4'h8 | a == 4'h9 | a == 4'hA |
a == 4'hB | a == 4'hD,
a == 4'h0 | a == 4'h2 | a == 4'h3 | a == 4'h5 | a == 4'h6 |
a == 4'h8 | a == 4'hB | a == 4'hC | a == 4'hD | a == 4'hE,
a == 4'h0 | a == 4'h2 | a == 4'h6 | a == 4'h8 | a == 4'hA |
a == 4'hB | a == 4'hC | a == 4'hD | a == 4'hE | a == 4'hF,
a == 4'h0 | a == 4'h4 | a == 4'h5 | a == 4'h6 | a == 4'h8 |
a == 4'h9 | a == 4'hA | a == 4'hB | a == 4'hE | a == 4'hF,
a == 4'h2 | a == 4'h3 | a == 4'h4 | a == 4'h5 | a == 4'h6 |
a == 4'h8 | a == 4'h9 | a == 4'hA | a == 4'hB | a == 4'hC |
a == 4'hD | a == 4'hE | a == 4'hF
};
endfunction
logic [3:0] fdd; // first digit data
logic [3:0] sdd; // second digit data
assign fdd = data[3:0];
assign sdd = data[7:4];
logic [6:0] fds; // first digit segment
logic [6:0] sds; // second digit segment
assign fds = to_segment(fdd);
assign sds = to_segment(sdd);
logic [31:0] clk_cnt;
logic [3:0] state;
/* state 0: idle
state 1-3: fds is fed to segment
state 4-6: sds is fed to segment
state 2: first digit (AN[0]) is driven high
state 5: second digit (AN[1]) is driven high */
always_ff @( posedge clk ) begin
if (~rstn) begin
clk_cnt <= 32'b0;
state <= 4'b0;
segment <= 7'b0;
digit_en <= 2'b0;
end
else begin
clk_cnt <= clk_cnt + 1;
if (clk_cnt == CLK_CNT_LIMIT) begin
clk_cnt <= 32'b0;
if (state == 4'd0) begin
state <= 4'd1;
segment <= fds;
end
else if (state == 4'd1) begin
state <= 4'd2;
digit_en <= 2'b01;
end
else if (state == 4'd2) begin
state <= 4'd3;
digit_en <= 2'b00;
end
else if (state == 4'd3) begin
state <= 4'd4;
segment <= sds;
end
else if (state == 4'd4) begin
state <= 4'd5;
digit_en <= 2'b10;
end
else if (state == 4'd5) begin
state <= 4'd6;
digit_en <= 2'b00;
end
else if (state == 4'd6) begin
state <= 4'd1;
segment <= fds;
end
end
end
end
endmodule
@bdm-k
Copy link
Author

bdm-k commented Oct 19, 2023

This module is designed for the Nexys A7 FPGA board.

The output signals segment and digit_en should be assigned to I/O pins as follows:

assign {CA, CB, CC, CD, CE, CF, CG} = ~segment;
assign {AN1, AN0} = ~digit_en;

Please refer to Nexys A7 Reference Manual for detailed information about these I/O pins.

The clock is assumed to be around 100 MHz.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment