使用Verilog先进先出(FIFO)
-
21-12-2019 - |
题
你好,我真的需要帮助这个,因为它让我疯狂的我疯狂的我使用spartan 3e,下面是fifo和之后的.ucf文件......我只是想知道为什么我不能写入/读到内存虽然当我生成二进制文件并编程FPGA时,我没有错误!
module fifo (
input [3:0] data_in,
input clk, rst, rd, wr,
output empty, full,
output reg [3:0] fifo_cnt,
output reg [3:0] data_out
);
reg [3:0] fifo_ram[0:7];
reg [2:0] rd_ptr, wr_ptr;
assign empty = (fifo_cnt==0);
assign full = (fifo_cnt==8);
always @( posedge clk )
begin: write
if(wr && !full) fifo_ram[wr_ptr] <= data_in;
else if(wr && rd) fifo_ram[wr_ptr] <= data_in;
end
always @( posedge clk )
begin: read
if(rd && !empty)
data_out <= fifo_ram[rd_ptr];
else if(rd && wr && empty)
data_out <= fifo_ram[rd_ptr];
end
always @( posedge clk )
begin: pointer
if( rst )
begin
wr_ptr <= 0;
rd_ptr <= 0;
end
else
begin
wr_ptr <= ((wr && !full)||(wr && rd)) ? wr_ptr+1 : wr_ptr;
rd_ptr <= ((rd && !empty)||(wr && rd)) ? rd_ptr+1 : rd_ptr;
end
end
always @( posedge clk )
begin: count
if( rst )
fifo_cnt <= 0;
else
begin
case ({wr,rd})
2'b00 : fifo_cnt <= fifo_cnt;
2'b01 : fifo_cnt <= (fifo_cnt==0) ? 0 : fifo_cnt-1;
2'b10 : fifo_cnt <= (fifo_cnt==8) ? 8 : fifo_cnt+1;
2'b11 : fifo_cnt <= fifo_cnt;
default: fifo_cnt <= fifo_cnt;
endcase
end
end
endmodule
.
# ==== Clock Source ====
NET "clk" LOC = "C9" | IOSTANDARD = LVCMOS33;
NET "clk" PERIOD = 5ns HIGH 40%;
NET "rst" LOC "D18" | IOSTANDARD = LVTTL | PULLDOWN ;
NET "wr" LOC "H13" | IOSTANDARD = LVTTL | PULLDOWN ;
NET "rd" LOC "K17" | IOSTANDARD = LVTTL | PULLDOWN ;
# ==== Slide Switches (SW) ====
NET "data_in<0>" LOC = "L13" | IOSTANDARD = LVTTL | PULLUP ; #// SW1
NET "data_in<1>" LOC = "L14" | IOSTANDARD = LVTTL | PULLUP ; #// SW2
NET "data_in<2>" LOC = "H18" | IOSTANDARD = LVTTL | PULLUP ; #// SW3
NET "data_in<3>" LOC = "N17" | IOSTANDARD = LVTTL | PULLUP ; #// SW4
# ==== Discrete LEDs (LED) ====
NET "data_out<3>" LOC = "F11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "data_out<2>" LOC = "E11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "data_out<1>" LOC = "E12" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "data_out<0>" LOC = "F12" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "empty" LOC "E9" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "full" LOC "F9" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
. 解决方案
好的,我在一个de0-nano板上尝试了它,它使用Altera Cyclone IV部分,并且能够将其工作,所以您的逻辑很好。我确实添加的一件事是RD和WR信号的边缘检测。
使用当前代码(和我的电路板)当您按下交换机时,我获得了许多连续的读数或写入。因此,单次按下WR开关将填充FIFO,单按下读取开关将清空FIFO。
我将RD输入信号重命名为RD_IN和WR信号到WR_IN并添加以下代码:
always @( posedge clk )
begin: edge_detect
rd_in_d <= rd_in;
wr_in_d <= wr_in;
rd = (rd_in && !rd_in_d);
wr = (wr_in && !wr_in_d);
end
.
在检测到RD_IN或WR_IN信号的上升沿时,才会为您提供单个RD / WR脉冲。
确保当您展示的开关不会按下开关时,开关信号很低。在我的电路板上,开关输入始终高(上拉电阻),并且在按下开关时才能降低。由于开关的按压创建逻辑低调,因此我必须颠倒RD / WR信号,让它们与代码正确地工作。
希望这有帮助!
不隶属于 StackOverflow