On 2007-08-19, Mark wrote:
> Petter Urkedal wrote:
>> There was a couple of bugs in the code I submitted, so here is a fixed
>> version which is also extended to 32x16->48 multiply. It runs in 16
>> cycles to produce a partial result which is fixed up with a 32 bit add.
>
> For this code, Synplify for Lattice tries for 200MHz and achieves 213MHz.
> Map reports 78 slices (109 4LUTs). PAR (inexplicably) tries for 548MHz and
> achieves 363MHz (the critical path is only two levels of logic). This
> seems a little fishy, but I'm not well-versed enough with Lattice's tools
> to give you a more detailed analysis as yet. I've really got to get down
> to reading Lattice's documentation...
Thank you for the result. I don't now anything more about the validity
of the PAR result, but if it's correct then maybe the attached version
can be run at 400 MHz since it only has one level of logic. I widened
it to 32x32->64 to make it more comparable to the radix version. This
one runs in about 32 cycles excluding the 1 CPU-cycle of post-processing.
Nevertheless, the Farhan's radix multiplier is much more straight
forward to use, since it does not require 3x or 4x clock, it already has
signed, and does not require post-processing the result, so I'm tending
towards using that one.
module mul32x32ser_helper(clock, start, x, y, za_o, zb_o);
input clock, start;
input[31:0] x;
input[31:0] y;
output[63:0] za_o;
output[31:0] zb_o;
reg[31:0] x_r;
reg[31:0] xy_r;
reg[31:0] s;
reg[31:0] c;
reg[31:0] v;
integer i;
always @(posedge clock) begin
if (start) begin
x_r <= x;
xy_r <= x & {32{y[0]}};
v <= y[31:1];
c <= 0;
s <= 0;
end else begin
v[30:0] <= v[31:1];
xy_r <= x_r & {32{v[0]}};
{c[0], v[31]} <= (xy_r[0] + c[0] + s[0]);
for (i = 1; i < 31; i = i + 1)
{c[i], s[i - 1]} <= (xy_r[i] + c[i] + s[i]);
{c[31], s[30]} <= (xy_r[31] + c[31]);
end
end
assign za_o = {s[31:0], v};
assign zb_o = c;
endmodule
module test();
reg clock, start;
reg[31:0] x;
reg[31:0] y;
wire[63:0] za;
wire[31:0] zb;
always #5 clock <= !clock;
mul32x32ser_helper mul(clock, start, x, y, za, zb);
parameter xc = 4114818721;
parameter yc = 4028281453;
wire[63:0] z = za + {zb, 32'b0};
initial begin
$monitor("%d za = %d, zb = %d, z = %d; %x", $time, za, zb, z, mul.xy_r);
clock <= 1;
start <= 1;
x <= xc;
y <= yc;
#1000;
start <= 0;
#320;
$display("Result should be %d", xc*yc);
$finish;
end
endmodule
_______________________________________________
Open-graphics mailing list
[email protected]
http://lists.duskglow.com/mailman/listinfo/open-graphics
List service provided by Duskglow Consulting, LLC (www.duskglow.com)