I want to make an output to a seven-segment indicator so that when the buttons are pressed, the letter on a certain segment is displayed, and when the switch is turned on, the entire word is displayed. The seven-segment units work with a dynamic display.
When switching the switch to the active state, the place bus is connected to the shift register and the 7-segment switches should switch according to it.
On waveforms, when switching the switch to the active state, bus "place" doesn't change and remains equal to the initial value of the shift register(?). The values when the signal is given from the buttons are correct
MODULE
module mux_decoder(
input btn_fir,
input btn_sec,
input btn_thi,
input btn_fou,
input sw_for_fullword,
input clk,
input rst,
//input BTNC,
//input SW[9],
output logic [3:0] place,
output [7:0] segments
);
typedef enum bit [7:0]
{
D = 8'b0111_1010,
N = 8'b1110_1100,
Y = 8'b0111_0110,
A = 8'b1110_1110,
space = 8'b0000_0000
}
seven_seg;
seven_seg letter;
logic [31:0] cnt;
always_ff@(posedge clk,posedge rst)begin
if(rst) cnt <= '0;
else cnt <= cnt+1'b1;
end
logic enable = (cnt[2:0] == '0);
logic [3:0]shift_reg;
always_ff@(posedge clk, posedge rst)begin
if (rst) shift_reg <= 4'b1;
else if(enable) shift_reg <= {shift_reg[0], shift_reg[3:1]};
end
always_comb begin
if(sw_for_fullword) place = shift_reg;
else place = {btn_fir, btn_sec,btn_thi,btn_fou};
end
always_comb begin
case (place)
4'b1000: letter = D;
4'b0100: letter = A;
4'b0010: letter = N;
4'b0001: letter = Y;
default: letter = space;
endcase
end
assign segments = letter;
endmodule
TB
module tb( );
logic[3:0] x;
logic[7:0] letter;
logic[3:0] place;
logic sw;
bit clk;
bit rst;
mux_decoder ms(.btn_fou(x[0]),.btn_fir(x[3]),.btn_sec(x[2]), .btn_thi(x[1]),.sw_for_fullword(sw),
.place(place), .segments(letter), .clk(clk), .rst(rst));
parameter CLK_PERIOD = 10;
always #(CLK_PERIOD/2) clk = ! clk;
initial begin
rst <= 1'b1;
repeat (2) @ (posedge clk);
rst <= 1'b0;
x = 4'b0001;
#20
x = 4'b0010;
#20
x=4'b0100;
#20;
x = 4'b1000;
#20
x='0;
sw = '1;
repeat (50) @ (posedge clk);
$finish;
end
At the moment when the switch switches to the active state, "place" is connected to a shift register, which shifts towards the higher digits every 16 cycles (due to enable). But on the waveform "place" stays the same. The question is why the place remains the same, although the shift register performs a shift and changes its value accordingly.
It is not sufficient to only look at signals in the testbench. You also need to look at waveforms inside the mux_decoder
module.
When I looked at the waveform of the enable
signal, it was unknown (x
). Change:
logic enable = (cnt[2:0] == '0);
to:
wire enable = (cnt[2:0] == '0);
Now, I see enable
become known:
Refer to IEEE Std 1800-2017, section 6.5 Nets and variables. You are driving enable
with a continuous assignment, which means it needs to be a "net" type, such as wire
. In this context, logic
is a "variable" type.