02-16-2010 10:59 AM
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
02-17-2010 08:41 AM
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.
02-20-2010 05:30 PM
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
05-07-2015 02:56 PM
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)