Verilog ModelSim模拟工作正常,但FPGA失败。我错过了什么?
很抱歉,如果这里有任何明显的东西,但我开始在这个新的FPGA的东西,我真的很享受到目前为止,但这是让我疯狂。 下面是一个块的Verilog代码,原则上对8位寄存器执行以下操作: 00000001 00000010 00000100 01000000 10000000 01000000 00100000Verilog ModelSim模拟工作正常,但FPGA失败。我错过了什么?,verilog,fpga,modelsim,quartus,intel-fpga,Verilog,Fpga,Modelsim,Quartus,Intel Fpga,很抱歉,如果这里有任何明显的东西,但我开始在这个新的FPGA的东西,我真的很享受到目前为止,但这是让我疯狂。 下面是一个块的Verilog代码,原则上对8位寄存器执行以下操作: 00000001 00000010 00000100 01000000 10000000 01000000 00100000 module bit_bouncer(clock, enable, bouncer_out); //INPUTS PORTS input clock; input enable; //OUTPU
module bit_bouncer(clock, enable, bouncer_out);
//INPUTS PORTS
input clock;
input enable;
//OUTPUTS PORTS
output bouncer_out;
//INPUT DATA TYPE
wire clock;
wire enable;
//OUTPUT DATA TYPE
reg [7:0] bouncer_out = 8'b00000001;
//Register to store data
reg direction = 0;
//CODE STARTS HERE
always @ (posedge clock) begin
if(enable) begin
bouncer_out = direction ? (bouncer_out >> 1) : (bouncer_out << 1);
direction <= (bouncer_out == 8'b00000001 || bouncer_out == 8'b10000000) ? ~direction : direction;
end
end
endmodule
模块位跳出器(时钟、启用、跳出);
//输入端口
输入时钟;
输入使能;
//输出端口
输出弹跳器输出;
//输入数据类型
线钟;
导线使能;
//输出数据类型
reg[7:0]bouncer_out=8'b00000001;
//注册以存储数据
reg方向=0;
//代码从这里开始
始终@(posedge时钟)开始
如果(启用)开始
保镖出=方向?(bouncer\u out>>1):(bouncer\u out您的位bouncer没有与系统时钟同步运行,也没有重置条件,这是造成故障的原因
更好的方法是使用时钟选通,并在主系统时钟的边缘对其进行测试。此外,来自触觉按钮的所有输入都应与系统时钟同步并去抖动。类似如下:
略图的
RTL
比特保镖
模块位反弹器
(
输入线时钟,
输入线复位,
输入线启用,
输入线时钟选通,
输出寄存器[7:0]弹跳器输出
);
//注册以存储数据
reg方向=0;
//代码从这里开始
始终@(posedge时钟)
开始
如果(重置)
开始
弹跳器_out=1;
方向=0;
结束
else if(启用和时钟选通)
开始
bouncer\u out=方向(bouncer\u out>>1):(bouncer\u out您的位bouncer没有与系统时钟同步运行,也没有重置条件,这是造成故障的原因
更好的方法是使用时钟选通,并在主系统时钟的边缘对其进行测试。此外,来自触觉按钮的所有输入都应与系统时钟同步并去抖动。类似如下:
略图的
RTL
比特保镖
模块位反弹器
(
输入线时钟,
输入线复位,
输入线启用,
输入线时钟选通,
输出寄存器[7:0]弹跳器输出
);
//注册以存储数据
reg方向=0;
//代码从这里开始
始终@(posedge时钟)
开始
如果(重置)
开始
弹跳器_out=1;
方向=0;
结束
else if(启用和时钟选通)
开始
bouncer\u out=direction?(bouncer\u out>>1):(bouncer\u out我尝试添加重置,但没有成功,但我自己制作了一个divideByN,并保留了Charles建议的重置,现在它工作正常。我想我在线获取的divideByN代码可能无法正确合成。以下是我的新divideByN代码:
module my_div_n #(parameter N = 1_000_000, parameter WIDTH = 20) (clock_in,
clock_out);
input wire clock_in;
output reg clock_out;
reg[WIDTH-2:0] counter; //WIDTH-2 because the last bit is taken care of by the fact that we flip the output (it acts as the last bit)
always @ (posedge clock_in) begin
counter <= counter + 19'b1;
if(counter == N>>1) begin
counter <= 0;
clock_out <= !clock_out;
end
end
endmodule
模块my_div n#(参数n=1_000,参数宽度=20)(时钟输入,
打卡下班);
输入线时钟输入;
输出寄存器时钟输出;
reg[WIDTH-2:0]counter;//WIDTH-2,因为最后一位由我们翻转输出(它充当最后一位)来处理
始终@(posedge时钟输入)开始
柜台1):(bouncer_out我尝试添加重置,但没有成功,但我已经制作了自己的divideByN并保留了Charles建议的重置,现在它工作正常。我认为我在网上获取的divideByN代码可能无法正确合成。这是我的新divideByN代码:
module my_div_n #(parameter N = 1_000_000, parameter WIDTH = 20) (clock_in,
clock_out);
input wire clock_in;
output reg clock_out;
reg[WIDTH-2:0] counter; //WIDTH-2 because the last bit is taken care of by the fact that we flip the output (it acts as the last bit)
always @ (posedge clock_in) begin
counter <= counter + 19'b1;
if(counter == N>>1) begin
counter <= 0;
clock_out <= !clock_out;
end
end
endmodule
模块my_div n#(参数n=1_000,参数宽度=20)(时钟输入,
打卡下班);
输入线时钟输入;
输出寄存器时钟输出;
reg[WIDTH-2:0]counter;//WIDTH-2,因为最后一位由我们翻转输出(它充当最后一位)来处理
始终@(posedge时钟输入)开始
计数器1):(bouncer_out您需要更详细地解释“故障”的含义。我们看不到您的FPGA板。我连接输出的8个LED以不可预测的方式一次点亮一个(它跳得非常快,停在一个LED上,然后又快速跳到另一个LED上,非常短暂地点亮其路径中的LED)您使用的是我们称之为“派生时钟”。一个由另一个时钟加逻辑生成的时钟。昨天有一个问题。请查看那里的评论。如果可能,请在整个设计中使用一个主时钟。(直到您在几年内实现多个时钟域和时钟域交叉)我已经按照你说的做了,使用了FPGA的直接时钟,我只通过分频器而不是PLL传递。现在我得到的唯一的东西是一个LED一直亮着,什么也没有发生(没有按钮按下也不会影响它,因为你可能会认为我的逻辑与我的启用相反).这是我的示意图,向您展示了我的实际设置,它仍然不起作用(仍然使用与以前相同的代码,但我将除数改为50000,以尝试从输入时钟获得1Hz信号):我一直将除数的宽度编辑为26,以说明N为50000(不是5000…愚蠢的我…)。但它仍然不起作用。现在LED像以前一样跳跃,但似乎受到分隔符N宽度的影响,即使缓冲区足够大,可以容纳所使用的N。您需要更详细地解释什么是“故障”意思是说。我们看不到你的FPGA板。我连接输出的8个LED以不可预测的方式一次点亮一个(它跳得非常快,停在一个LED上,然后又快速跳到另一个LED上,非常短暂地点亮其路径中的LED)您使用的是我们称之为“派生时钟”。一个由另一个时钟加逻辑生成的时钟。昨天有一个问题。请查看那里的评论。如果可能,请在整个设计中使用一个主时钟。(直到您在几年内实现多个时钟域和时钟域交叉)
module ClockStrobe
#(
parameter MAX_COUNT = 50000000
)
(
input wire clock,
input wire reset,
output reg clock_strobe
);
reg [$clog2(MAX_COUNT) - 1: 0] counter;
always @(posedge clock)
begin
if (reset)
begin
counter <= 0;
end
else
begin
counter <= counter + 1;
if (counter == MAX_COUNT)
begin
clock_strobe <= 1;
counter <= 0;
end
else
begin
clock_strobe <= 0;
end
end
end
endmodule
module Sync
(
input wire clock,
input wire in,
output reg out
);
reg [2:0] sync_buffer;
initial
begin
out = 0;
sync_buffer = 3'd0;
end
always @*
begin
out <= sync_buffer[2];
end
always @(posedge clock)
begin
sync_buffer[0] <= in;
sync_buffer[2:1] <= sync_buffer[1:0];
end
endmodule
module Debounce
#(
parameter MAX_COUNT = 2500000
)
(
input wire clock,
input wire in,
output reg out
);
reg previous_in;
reg [$clog2(MAX_COUNT) - 1:0] counter;
initial begin
previous_in = 0;
counter = 0;
out = 0;
end
always @(posedge clock)
begin
counter <= counter + 1;
if (counter == MAX_COUNT)
begin
out <= previous_in;
counter <= 0;
end
else if (in != previous_in)
begin
counter <= 0;
end
previous_in <= in;
end
endmodule
module my_div_n #(parameter N = 1_000_000, parameter WIDTH = 20) (clock_in,
clock_out);
input wire clock_in;
output reg clock_out;
reg[WIDTH-2:0] counter; //WIDTH-2 because the last bit is taken care of by the fact that we flip the output (it acts as the last bit)
always @ (posedge clock_in) begin
counter <= counter + 19'b1;
if(counter == N>>1) begin
counter <= 0;
clock_out <= !clock_out;
end
end
endmodule
module bit_bouncer(clock, enable, reset, bouncer_out);
//INPUTS PORTS
input clock;
input enable;
input reset;
//OUTPUTS PORTS
output [7:0] bouncer_out;
//INPUT DATA TYPE
wire clock;
wire enable;
wire reset;
//OUTPUT DATA TYPE
reg [7:0] bouncer_out;
//Register to store data
reg direction;
//CODE STARTS HERE
always @ (posedge clock) begin
if(reset) begin
bouncer_out <= 8'b00000001;
direction <= 0;
end
else if(enable) begin
bouncer_out = direction ? (bouncer_out >> 1) : (bouncer_out << 1);
direction <= (bouncer_out == 8'b00000001 || bouncer_out == 8'b10000000) ? ~direction : direction;
end
end
endmodule