I currently have the following verilog expression...

wire [15:0] address_delta = (rx_address_in * 8 + (rx_eof_in ? rx_len_in : 8)) - (seek_address + OUT_BYTES);


rx_address_in is 13 bits and OUT_BYTES is a parameter which is an integer constant (so I guess 32 bits). I am assuming the 8x multiplication will get optimized into a left shift of 3. If this is a bad assumption to make please let me know. I am using the latest Vivado.

Right now my design is having trouble meeting timing. Although my address_delta is only 16 bits, since I am using 32 bit constants inside the expression which I think might cause the operations to be carried out at a higher precision than necessary. How would you rewrite this expression for efficiency or is it fine the way it is?

I am thinking I could do something like this...

wire [15:0] seek_end = (seek_address + OUT_BYTES);
wire [15:0] address_delta = ((rx_address_in << 2'd3) + (rx_eof_in ? rx_len_in : 4'd8)) - seek_end;

• Have you looked in the timing report to identify the critical path? Synthesis tools are pretty good at discarding logic that isn't needed, so I doubt that you really have identified the problem. – Elliot Alderson Jul 11 '18 at 19:09

HDL languages do not work like C. There still is a continuous timing path from seek_address to address_delta.
To break the path you must e.g. insert a register. But that may stop your design from working as seek_end will arrive one clock cycle later.
You do not tell us how fast your design must be, but as Elliot Alderson already suggest in the comment: three 16 bit adders are rarely critical. (The rx_address_in << 2'd3 does not cause any delay.) Unless this expression is part of a logic cone.
• I think the OP is saying that using wire[15:0] will force the intermediate result to be truncated to 16 bits, which might help meet timing since less stuff is computed. – immibis Jul 12 '18 at 2:06