我在verilog编码七段显示器时遇到了一些问题。我希望将1位增加1并在9之后将其翻转为0.我已经进行了大量调试并查看了示例但我似乎无法找到问题。我的代码:
module counter(output sega, segb, segc, segd, sege, segf, segg);
OSCH #("2.08") osc_int ( //"2.03" specifies the operating frequency, 2.03 MHz. Other clock frequencies can be found in the MachX02's documentation
.STDBY(1'b0), //Specifies active state
.OSC(clk), //Outputs clock signal to 'clk' net
.SEDSTDBY());
reg [21:0] cnt;
wire clk_slow = cnt[21]; //clock at 1 Hz
reg [3:0] BCD; //represents the states of the counter
always @(posedge clk)
begin
begin
cnt <= cnt+1;
end
begin
if(clk_slow) BCD <= (BCD ==4'h9 ? 4'h0 : BCD+4'b0001); //increments state by 1
end
end
reg [6:0] seg;
always @(*)
begin
case(BCD)
//gfedcba
4'b0000: seg = 7'b1000000; //0
4'b0001: seg = 7'b1111001; //1
4'b0010: seg = 7'b0100100; //2
4'b0011: seg = 7'b0110000; //3
4'b0100: seg = 7'b0011001; //4
4'b0101: seg = 7'b0010010; //5
4'b0110: seg = 7'b0000010; //6
4'b0111: seg = 7'b1111000; //7
4'b1000: seg = 7'b0000000; //8
4'b1001: seg = 7'b0011000; //9
default seg = 7'b0111111;
endcase
end
assign {segg, segf, sege, segd, segc, segb, sega} = seg;
endmodule
因此,当它运行时,我的LED会每隔一段时间点亮正确的数字。在这种情况下,它会亮起0,2,4,6,8并重复。在每个数字之间,LED点亮,但不亮(昏暗的'8')。当我切换机箱的顺序但是将数字保持在同一位置时(例如现在的情况b0000为9号),LED点亮了9,7,5,3,1 ......由于某种原因,我的LED arnt响应任何“奇怪”情况(即0001,0011 ......)。非常感谢任何帮助排序,因为我已经花了很多时间尝试调试。
我正在使用Diamond Lattice FPGA。它有一个板载时钟(我的代码中的第一个模块)。我在clock_slow将它减慢到1赫兹。
答案 0 :(得分:4)
您的问题与这些问题有关:
always @(posedge clk)
begin
cnt <= cnt+1;
if(clk_slow) BCD <= (BCD ==4'h9 ? 4'h0 : BCD+4'b0001); //increments state by 1
end
由于clk
比clk_slow
快,因此if条件将在多个时钟周期内为真('clk_slow
为clk
个周期的原因BCD
为高。这就是always
将不止一次递增的原因。我建议你将这两条指令分成两个独立的always @(posedge clk) begin
cnt <= cnt + 1;
end
always @(posedge clk_slow) begin
BCD <= (BCD ==4'h9 ? 4'h0 : BCD+4'b0001); //increments state by 1
end
块:
#include <pic.h>
#include <stdint.h>
#define _XTAL_FREQ 20000000
void main()
{
unit8_t pressed = 0;
bool blink = 0;
TRISB = 0x01;
PORTB = 0x00;
while(1)
{
// Button pressed for the first time
if ((RB0 == 1) && (pressed == 0))
{
pressed = 1;
}
// Button released = valid
else if ((RB0 == 0) && (pressed == 1))
{
pressed = 2;
}
if (pressed == 2)
{
blink ^= 1;
pressed = 0;
}
if (blink == 1)
{
PORTB ^= 0xFE;
__delay_ms(250);
}
}
}