Question

Hello i really need help with this cuz its driving me crazy im using Spartan 3E and below is the .v file for FIFO and after that .ucf file ... im just wondering why i cant write/read to the memory even though i get no errors when i generate the binary file and program the 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 ;
Was it helpful?

Solution

Okay, I tried this on a de0-nano board which uses an Altera Cyclone IV part and was able to get it to work, so your logic is good. The one thing that I did add is an edge detect for the rd and wr signals.

With your current code (and my board) when you depress a switch I was getting many contiguous reads or writes. So a single press of the wr switch would fill the fifo and a single press of the read switch would empty the fifo.

I renamed your rd input signal to rd_in and the wr signal to wr_in and added the following code:

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

which will give you a single rd/wr pulse only when a rising edge of the rd_in or wr_in signals is detected.

Make sure that your switch signals are low when the switch is not depressed as it appears you're assuming. On my board the switch inputs are always high (pull-up resistors) and only go low when the switch is depressed. Since a press of the switch creates a logic low condition I had to invert the rd/wr signals to get them to work correctly with your code.

Hope this helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top