K
Kevin Neilson
Guest
Here's another example that shows just how far removed we are from high-level synthesis.
I need to multiply a 10-bit number by 956. I could use a DSP48, but it's overkill, and to meet timing I'd probably have to pipeline it fully and have 3 cycles of latency. So I write this code and force Vivado not to use DSP48s:
reg [9:0] x; // multiplicand
reg [19:0] p; // product
always@(posedge clk)
p <= x*956;
This has 58 LUTs, 3 separate columns of carry chains, and fails timing at my clock speed.
I'd guess that the synthesizer fully optimizes a simple constant multiplier, but just for fun I go down a level of abstraction, looking at the binary representation of 956, and making a CSD (canonical signed digit) version:
reg [9:0] x; // multiplicand
reg [19:0] p; // product
always@(posedge clk)
p <= (x<<10) - (x<<6) - (x<<2); // same as x*956
Results: 19 LUTs, meets timing with 850ps slack. There is only 1 carry chain (ternary add?).
So what I am saying is that I can't even use the '*' sign. I have to go down a level of abstraction in order to make a multiplier that will meet timing. If I can't use the multiply sign, why would I believe I could use C code?
I need to multiply a 10-bit number by 956. I could use a DSP48, but it's overkill, and to meet timing I'd probably have to pipeline it fully and have 3 cycles of latency. So I write this code and force Vivado not to use DSP48s:
reg [9:0] x; // multiplicand
reg [19:0] p; // product
always@(posedge clk)
p <= x*956;
This has 58 LUTs, 3 separate columns of carry chains, and fails timing at my clock speed.
I'd guess that the synthesizer fully optimizes a simple constant multiplier, but just for fun I go down a level of abstraction, looking at the binary representation of 956, and making a CSD (canonical signed digit) version:
reg [9:0] x; // multiplicand
reg [19:0] p; // product
always@(posedge clk)
p <= (x<<10) - (x<<6) - (x<<2); // same as x*956
Results: 19 LUTs, meets timing with 850ps slack. There is only 1 carry chain (ternary add?).
So what I am saying is that I can't even use the '*' sign. I have to go down a level of abstraction in order to make a multiplier that will meet timing. If I can't use the multiply sign, why would I believe I could use C code?