Implement Counter/BCD/Segments
This commit is contained in:
41
BinToBcd.sv
Normal file
41
BinToBcd.sv
Normal 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
37
Counter.sv
Normal 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
48
SegDriver.sv
Normal 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
33
SegmentDisplay.sv
Normal 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
|
Reference in New Issue
Block a user