Verilog를 사용하는 FIFO 첫 번째 (FIFO)
-
21-12-2019 - |
문제
안녕하세요, 나는 정말로이 사촌에 대한 도움이 필요합니다. Spartan 3e를 사용하여 미친 IM을 운전하고 있습니다.바이너리 파일을 생성하고 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 ;
. 해결책
알리, 알테라 사이클론 IV 부분을 사용하는 De0-Nano 보드 에서이 작업을 수행 했으므로 작업을 수행 할 수 있었기 때문에 논리가 좋습니다. 내가 추가 한 한 가지는 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 펄스를 제공합니다.
스위치가 나타나면 스위치가 우울하지 않으면 스위치 신호가 부족 해지는지 확인하십시오. 내 보드에서 스위치 입력은 항상 높습니다 (풀업 저항)은 스위치가 우울할 때만 낮습니다. 스위치를 누르면 Logic Low Condition을 만듭니다. RD / WR 신호를 반전하여 코드로 올바르게 작동하도록하십시오.
이 도움이되기를 바랍니다!
제휴하지 않습니다 StackOverflow