1

Implement Counter/BCD/Segments

This commit is contained in:
2023-03-23 21:30:10 +01:00
parent 8a3b8c4fbe
commit d5670b0087
4 changed files with 159 additions and 0 deletions

41
BinToBcd.sv Normal file
View File

@ -0,0 +1,41 @@
`default_nettype none
// https://en.wikipedia.org/wiki/Double_dabble
module BinToBcd
#(parameter integer DIGITS = 4,
parameter integer WIDTH = 14)(
input var logic[WIDTH-1:0] binin,
output var logic[3:0] bcdout[DIGITS-1:0]
);
// Easier to operate on a packed array
var logic[DIGITS*4-1:0] bcdscratch;
integer ii, jj;
always @(binin) begin
bcdscratch = '0;
// Iterate over each bit
for (ii = 0; ii < WIDTH; ii = ii + 1) begin
// Iterate over each digit
for (jj = 0; jj < DIGITS; jj = jj + 1) begin
// Add three, if digit >= 5
if (bcdscratch[(jj+1)*4-1 -: 4] >= 5) begin
// Select the digit: 1st digit [7:4], 2nd digit [11:8], etc.
// The -: or +: syntax specify the length of the slice
bcdscratch[(jj+1)*4-1 -: 4] = bcdscratch[(jj+1)*4-1 -: 4] + 3;
end
end
// Shift to left and fill with lsb with corresponding binin bit
bcdscratch = {bcdscratch[DIGITS*4-2:0], binin[WIDTH-1-ii]};
end
// Iterate over each digit
for (jj = 0; jj < DIGITS; jj = jj + 1) begin
// Assign scratch buffer to bcdout
bcdout[jj] = bcdscratch[(jj+1)*4-1 -: 4];
end
end
endmodule

37
Counter.sv Normal file
View File

@ -0,0 +1,37 @@
`default_nettype none
module Counter
#(parameter integer DIGITS = 4,
parameter integer WIDTH = 14)(
input var logic clock,
input var logic reset,
input var logic decrement,
output var logic[WIDTH-1:0] binout
);
var logic[WIDTH-1:0] countervalue;
always @(posedge clock or posedge reset)
if (reset) begin
// Reset the counter to 0
countervalue <= '0;
end else if (~decrement) begin
// Increment the counter
if (countervalue == 10**DIGITS-1) begin
// Overflow
countervalue <= '0;
end else begin
countervalue <= countervalue + 1;
end
end else if (decrement) begin
// Decrement the Counter
if (countervalue == 0) begin
// Underflow
countervalue <= '{10**DIGITS-1};
end else begin
countervalue <= countervalue - 1;
end
end
assign binout = countervalue;
endmodule

48
SegDriver.sv Normal file
View File

@ -0,0 +1,48 @@
`default_nettype none
module SingleSegDriver(
input var logic[3:0] bcdin,
output var logic[6:0] segments
);
// The segments are enabled on a low logic level
always_comb case (bcdin)
// +----a----+
// | |
// f b
// | |
// +----g----+
// | |
// e c
// | |
// +----d----+ gfedcba
4'b0000: segments = ~7'b0111111;
4'b0001: segments = ~7'b0000110;
4'b0010: segments = ~7'b1011011;
4'b0011: segments = ~7'b1001111;
4'b0100: segments = ~7'b1100110;
4'b0101: segments = ~7'b1101101;
4'b0110: segments = ~7'b1111101;
4'b0111: segments = ~7'b0000111;
4'b1000: segments = ~7'b1111111;
4'b1001: segments = ~7'b1100111;
default: segments = ~7'b0;
endcase
endmodule
module SegDriver
#(parameter integer DIGITS = 4)(
input var logic[3:0] bcdin[DIGITS-1:0],
output var logic[6:0] segments[DIGITS-1:0]
);
genvar ii;
generate
for (ii = 0; ii < DIGITS; ii = ii + 1) begin : generate_seg_drivers
SingleSegDriver ssd(
.bcdin(bcdin[ii]),
.segments(segments[ii])
);
end
endgenerate
endmodule

33
SegmentDisplay.sv Normal file
View File

@ -0,0 +1,33 @@
`default_nettype none
module SegmentDisplay
#(parameter integer DIGITS = 4,
parameter integer WIDTH = 14)(
input var logic reset,
input var logic clock,
input var logic decrement,
output var logic[6:0] segments[DIGITS-1:0]
);
tri[WIDTH-1:0] cntout;
tri[3:0] bcdout[DIGITS-1:0];
Counter cnt(
// The KEY's provide a high logic level when not pressed
.clock(~clock),
.reset(~reset),
.decrement(decrement),
.binout(cntout)
);
BinToBcd bcd(
.binin(cntout),
.bcdout(bcdout)
);
SegDriver seg(
.bcdin(bcdout),
.segments(segments)
);
endmodule