Hello,
I have this blob of Verilog -- don't worry about reading the whole lot, the bold parts are the important part.
input wire drdy;
input wire dclk;
input wire din;
output reg tx;
output hob;
reg [7:0] counter = 0;
reg [7:0] shiftreg;
reg [5:0] uartcount;
always @(negedge dclk)
begin
shiftreg <= {shiftreg[6:0],din};
if (drdy)
counter <= 0;
else begin
if (counter[4:0] == 5'd8)
uartcount <= 6'd3;
else if (uartcount == 6'd48)
begin end
else if (uartcount[2:0] == 3'd0)
uartcount <= uartcount + 6'd7;
else
uartcount <= uartcount + 6'd1;
if (uartcount[3])
tx <= shiftreg[uartcount[5:4]];
else
tx <= !uartcount[0];
counter <= counter + 1;
end
end
Now, I'm not trying to win the readable code of the year awards here, but it's my understanding that commands within a begin/end block are executed sort-of-sequentially; so on the negative edge of dclk, the shift register first has din shifted into position zero. And then, sort-of-subsequently, tx is assigned to one of shiftreg[0, 1, 2 or 3], based on the contents of uartcount[5:4]. So, the the value of din should be loaded into the tx register on a single clock edge. However, if I compile/fit this using ispLEVER and inspect the fitter's output, we see that the value of din cannot possibly make it to the tx reg in a single clock cycle; it must be transferred to shiftreg_0.Q on one cycle, and then only arrives to tx.Q on the second cycle. AFAICT, this is specifically not what I asked for in my Verilog code above?
shiftreg_0_.D = din ; (1 pterm, 1 signal)
shiftreg_0_.C = !dclk ; (1 pterm, 1 signal)
shiftreg_1_.D = shiftreg_0_.Q ; (1 pterm, 1 signal)
shiftreg_1_.C = !dclk ; (1 pterm, 1 signal)
shiftreg_2_.D = shiftreg_1_.Q ; (1 pterm, 1 signal)
shiftreg_2_.C = !dclk ; (1 pterm, 1 signal)
shiftreg_3_.D = shiftreg_2_.Q ; (1 pterm, 1 signal)
shiftreg_3_.C = !dclk ; (1 pterm, 1 signal)
tx.D = uartcount_3_.Q & shiftreg_0_.Q & !uartcount_4_.Q & !uartcount_5_.Q
# uartcount_3_.Q & shiftreg_1_.Q & uartcount_4_.Q & !uartcount_5_.Q
# uartcount_3_.Q & shiftreg_2_.Q & !uartcount_4_.Q & uartcount_5_.Q
# uartcount_3_.Q & shiftreg_3_.Q & uartcount_4_.Q & uartcount_5_.Q
# !uartcount_0_.Q & !uartcount_3_.Q ; (5 pterms, 8 signals)
tx.C = !dclk ; (1 pterm, 1 signal)
tx.CE = !drdy ; (1 pterm, 1 signal)
So, is the compiler/fitter broken, or is my understanding incorrect?