cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
keithxilinx1
Participant
Participant
8,035 Views
Registered: ‎02-15-2009

verilog FIFO help

I'm trying to use the FIFO generated from the fifo generator v 5.3.  This is a common clock fifo.

 

I'm trying to connect the FIFO to a transmitter, so that any time the FIFO is not empty, it transmits the contents.

 

Here's my read-fifo state machine code:

 

 

/ instantiate the fifo

myfifo uartfifo (
.clk(clk),
.rst(rst),
.din(din), // Bus [7 : 0]
.wr_en(wr_en),
.rd_en(rd_en),
.dout(dout), // Bus [7 : 0]
.full(full),
.almost_full(almost_full),
.wr_ack(wr_ack),
.empty(empty),
.valid(valid),
.data_count(data_count));

async_transmitter serializer(.clk(clk), .TxD(serrx), .TxD_start(TxD_start), .TxD_data(dout), .TxD_busy(TxD_busy));

// state machine for fifo to uart
parameter IDLE_FIFO = 4'b0001;
parameter REQ_RDEN = 4'b0010;
parameter CALLXMIT = 4'b0100;
parameter WAITXMIT = 4'b1000;

reg [3:0] state_fifo = IDLE_FIFO;



always @(state_fifo)
begin
case (state_fifo)
IDLE_FIFO:
begin
rd_en = 1'b0;
TxD_start = 1'b0;
end

REQ_RDEN:
begin
rd_en = 1'b1;
TxD_start = 1'b0;
end

CALLXMIT:
begin
rd_en = 1'b0;
TxD_start = 1'b1;
end

WAITXMIT:
begin
rd_en = 1'b0;
TxD_start = 1'b0;
end

default:
begin
rd_en = 1'b0;
TxD_start = 1'b0;
end
endcase
end

// this part of the state machine governs transitions from one state to the next

always @(posedge clk or posedge rst)
begin
if (rst)
state_fifo = IDLE_FIFO;
else
case (state_fifo)
IDLE_FIFO:
if (!empty)
state_fifo = REQ_RDEN;
else
state_fifo = IDLE_FIFO;

REQ_RDEN:
if (valid) begin

state_fifo = CALLXMIT;

end

else
state_fifo = REQ_RDEN;

CALLXMIT:
if (TxD_busy)
state_fifo = WAITXMIT;
else
state_fifo = CALLXMIT;

WAITXMIT:
if (!TxD_busy)
state_fifo = IDLE_FIFO;
endcase
end

 

 And here's my write fifo state machine:

 

 

always @(state_writefifo)
begin
case (state_writefifo)
zero:
begin
din = 8'd65;
wr_en = 0;
end

one:
begin
//din = 8'd65;
wr_en = 1;
end

default:
begin
din = 8'd0;
wr_en = 0;
end
endcase
end

always @(posedge clk or posedge rst)
begin
if (rst)
state_writefifo = zero;
else
case (state_writefifo)
zero:
begin

if (( !full) && (!almost_full)) begin

state_writefifo = one;
end

end

one:
begin

if (wr_ack) begin

state_writefifo = two;
end

end

default:

begin
state_writefifo = two;
end
endcase
end

 

 

 

Sorry for the formatting, I have no clue what's happening  cut/pasting out of ISE.

 

Am I on the right track here?

 

Thanks

 

Keith

 

 

 

Tags (3)
0 Kudos
Reply
3 Replies
bassman59
Historian
Historian
8,017 Views
Registered: ‎02-25-2008

Two questions:

 

a) What's the question? You posted code but you didn't say that anything was wrong with it, nor did you say that you simulated it, or anything.

 

b) Don't use the two-process state machine construct. 

----------------------------Yes, I do this for a living.
0 Kudos
Reply
keithxilinx1
Participant
Participant
7,994 Views
Registered: ‎02-15-2009

Sorry, I should have been more clear.

 

I've since abandoned my ugly state machines -- but still having basic the same problem.

 

module ftpfs( input clk, input usbres, output [7:0] leds, output usbrx, output io29, output io30 ); //fifo variables reg [7:0] din; reg wr_en; reg rd_en; wire [7:0] dout; wire full; wire almost_full; wire wr_ack; wire empty; wire valid; wire [7:0] data_count; // transmitter variables reg [7:0] TxD_data; reg rd_en_dly; wire TxD_busy; reg [4:0] characteradd; //instantiate the fifo myfifo fifoinstance ( .clk(clk), /*.rst(rst),*/ .din(din), // Bus [7 : 0] .wr_en(wr_en), .rd_en(rd_en), .dout(dout), // Bus [7 : 0] .full(full), .almost_full(almost_full), .wr_ack(wr_ack), .empty(empty), .valid(valid), .data_count(data_count)); // Bus [7 : 0] //instantiate the transmitter async_transmitter serializer(.clk(clk), .TxD(usbrx), .TxD_start(rd_en_dly), .TxD_data(dout), .TxD_busy(TxD_busy)); assign leds[0] = full; assign io29 = rd_en; assign io30 = TxD_busy; always @(posedge clk) begin if ((!empty) && (!TxD_busy) && (!usbres)) rd_en=1; else rd_en=0; rd_en_dly <= rd_en; if (!full) begin din = 8'd65+characteradd; wr_en = 1; characteradd = characteradd + 1; end else wr_en = 0; end endmodule

 


 

 

I have the async transmitter code attached to a TTL->USB converter.  The transmitter code is located here, if needbe.  http://www.fpga4fun.com/files/async.zip

 

So I check to see that the FIFO's not empty, that the transmitter isn't busy, and that my converter isn't telling me to STOP, then I assert rd_en to the FIFO to read a byte, otherwise I deassert rd_en, to check at the next clock cycle.

 

The code to write follows that, and should be clear enough.

 

THE PROBLEM: I get this "BDFHJLNPRTVXZ\^`BDFHJLNPRTVXZ\^`BDFHJLNPRT".  It skips every other character.  I'm not just over-running the PC, I've got a logic analyzer hooked up, and I can see it skipping a byte.

 

I've tried to simulate, but there are a variety of problems --- not the least being key register waveforms are all RED, XXXXXX, aka unknown state.  I'm using ISIM.

 

THE QUESTION:  What am I doing wrong?  I brought a couple signals off the board, and there is a 1-1 match of rd_en_dly and TxD_busy, so I don't think I'm requesting more than one byte, and only transmitting one.

 

Thanks

 

Keith

 

 

0 Kudos
Reply
lbenites
Observer
Observer
3,461 Views
Registered: ‎08-15-2014

This is a thousand year old question, but maybe it helps someone.

 

Normally, when your FIFO goes empty or when the receiver can't take data you have to stop right away (combinatorially)

 

If your FIFO goes empty you can't read one more time and expect valid data. This type of error will result in the last/first data of a burst being incorrect (or missing if it was the receiver that asked you to stop)

0 Kudos
Reply