Verilog HDL,来自FPGA的用户输入
我目前正在使用从我的学校获得的FPGA进行Verilog HDL项目(我正在运行Quartus II版本10.1和11.0(我已经尝试了这两种版本))。我得到了一个非常奇怪的错误,我无法找出我的生活 我正在开发一个莫尔斯电码程序,它可以检测点和破折号,然后根据输入在十六进制显示器上输出相应的字母。十六进制显示效果很好,但我的UserInput模块似乎什么都不做Verilog HDL,来自FPGA的用户输入,verilog,hardware-interface,Verilog,Hardware Interface,我目前正在使用从我的学校获得的FPGA进行Verilog HDL项目(我正在运行Quartus II版本10.1和11.0(我已经尝试了这两种版本))。我得到了一个非常奇怪的错误,我无法找出我的生活 我正在开发一个莫尔斯电码程序,它可以检测点和破折号,然后根据输入在十六进制显示器上输出相应的字母。十六进制显示效果很好,但我的UserInput模块似乎什么都不做 module UserInput(Clock, reset, in, out); input Clock, reset, in; out
module UserInput(Clock, reset, in, out);
input Clock, reset, in;
output reg [1:0] out;
wire [2:0] PS;
reg [2:0] NS;
parameter NONE = 2'b00, DOT = 2'b01, DASH = 2'b11; //For Output
parameter UP = 3'b000, SHORT0 = 3'b001, SHORT1 = 3'b010, UP_DOT = 3'b011, LONG = 3'b100, UP_DASH = 3'b101;
//Active High
always@(PS or in)
case (PS)
UP: if (in) NS = SHORT0;
else NS = UP;
SHORT0: if (in) NS = SHORT1;
else NS = UP_DOT;
SHORT1: if (in) NS = LONG;
else NS = UP_DOT;
UP_DOT: NS = UP;
LONG: if (in) NS = LONG;
else NS = UP_DASH;
UP_DASH: NS = UP;
default: NS = 3'bxxx;
endcase
always@(PS)
case (PS)
UP: out = NONE;
SHORT0: out = NONE;
SHORT1: out = NONE;
UP_DOT: out = DOT;
LONG: out = NONE;
UP_DASH: out = DASH;
default: out = 2'bxx;
endcase
D_FF dff0 (PS[0], NS[0], reset, Clock);
D_FF dff1 (PS[1], NS[1], reset, Clock);
D_FF dff2 (PS[2], NS[2], reset, Clock);
endmodule
module D_FF (q, d, reset, clk);
input d, reset, clk;
output reg q;
always@(posedge clk or posedge reset)
begin
if (reset) q = 0;
else q = d;
end
endmodule
模块的输入是FPGA上的一个键。UserInput模块表示的FSM在t=0时键处于“向上”状态。然后,如果有输入,它将通过SHORT0或SHORT1,最后是LONG。如果在这些状态中的任何一种状态下释放密钥,它们将进入相应的中间向上状态,并提供“点”或“破折号”输出
然而,当我把它连接到我的FPGA时,我什么也得不到。从我的测试来看,它似乎从未离开“向上”状态。甚至我的模拟也没有给我任何东西。其次,我尝试从不同的项目连接不同的UserInput模块(我知道这是一个可行的项目),但仍然一无所获。在我丢失的Verilog的背景中有什么事情吗
以下是模拟波形的图像:
DFf 0、1和2是PS的位0、1和2。我的模拟不允许显示NS。我觉得你的代码很糟糕(我想你想听,因为你的代码不工作)。这看起来像是时间问题和设计缺陷的结合
让我们浏览一下您的波形视图,看看是否无法了解发生了什么
信号输入变高,触发“始终”阻塞。PS是0,所以我们将NS设置为1。这不是上升时钟边缘的时间,因此它不会在DFF中触发(正如您所怀疑的),更不用说它会在下一个时钟边缘被捕获
信号输入变低,这会触发一个always块,PS为0,所以我们将NS设置为0。这会在上升时钟边缘的时间发生,并在DFF中捕获(argh,我们错过了NS信号,按照我们的要求变为1)
另外,有人提到,在断言重置时,触发器被断言有一个错误。这不是问题:重置是同步的。因此,在下一个上升时钟边缘,DFF重置为0
那么,解决方案是什么(对我来说就像是家庭作业,希望你已经解决了这个问题!):
它应该是这样的(我没有模拟它,所以不能保证):
模块用户输入(时钟、复位、输入、输出);
输入时钟,复位,输入;
输出[1:0]输出;
//输出参数
参数IDLE=2'b00;
参数点=2'b01;
参数DASH=2'b10;
//密克罗尼西亚联邦
参数低=3'b000;
参数SHORT1=3'b001;
参数SHORT2=3'b010;
参数长=3'b100;
reg[2:0]状态;
连接[1:0]下一个输出;
导线[2:0]下一个_状态;
始终@(posedge clk)
开始
如果(重置)
开始
当你说它在模拟中不起作用时,你是说你正在应用适当的重置、时钟和刺激,而DFF从未改变?你能提供测试台代码吗?是的,这是正确的。不幸的是,我不知道如何编写测试台代码。我被教导使用Altera大学的程序模拟器,它提供了一种更加图形化的方法。然而,当我使用Altera UP模拟器进行模拟,并提供适当的重置、时钟和in刺激时,DFF不会改变。没有更多信息,我不知道该说什么。我认为,如果你没有混淆复位极性或其他什么的话,你那里的东西应该是有效的。如果你正在调试Wave,也许你可以放一个Wave的屏幕截图,显示它不工作时的相关信号(重置、clk、NS、PS、in)?我添加了一个模拟图像。我不知道这是否有帮助,但我得到了一个关键警告“未满足时间要求”。这可能是罪魁祸首吗?如果是这样,我该如何解决?另外,谢谢你抽出时间来帮助我。我真的很感激。你是在模拟一个带后注释的网表吗?如果计时失败,那么您的模拟将不会有用。
Module UserInput (clk, reset, in, out);
input clk, reset, in;
output [1:0] out;
// output parameters
parameter IDLE = 2'b00;
parameter DOT = 2'b01;
parameter DASH = 2'b10;
// FSM states
parameter LOW = 3'b000;
parameter SHORT1 = 3'b001;
parameter SHORT2 = 3'b010;
parameter LONG = 3'b100;
reg [2:0] state;
wire [1:0] next_out;
wire [2:0] next_state;
always @(posedge clk)
begin
if (reset)
begin
out <= IDLE;
state <= LOW;
end;
else
begin
out <= next_out;
state <= next_state;
end
end if;
end
always @(*)
begin
case (state)
LOW:
next_out = IDLE;
next_state = (in? SHORT1 : LOW);
SHORT1:
begin
next_state = (in? SHORT2: LOW);
next_out = (in? IDLE : DOT);
end;
SHORT2:
next_state = (in? LONG: LOW);
next_out = (in? IDLE : DOT);
LONG:
next_state = (in? LONG : LOW);
next_out = (in? IDLE : DASH);
default:
// we shouldn't get here!!
next_state = LOW;
next_out = IDLE;
end;
end module;
module in_buffer (clk, reset, in, out);
input clk, reset, in;
output out;
reg buf1, buf2;
always @ (posedge clk)
begin
if (reset)
begin
out <= 0;
buf1 <= 0;
buf2 <= 0;
end
else
out <= buf2;
buf2 <= buf1;
buf1 <= in;
end
end