bit manipulation - Verilog access specific bits -
i have problem in accessing 32 significant , 32 least significant bits in verilog. have written following code error "illegal part-select expression" point here don't have access 64 bit register. please help.
`mlt: begin if (multstate==0) begin {c,res}<={a*b}[31:0]; multstate=1; end else begin {c,res}<={a*b}[63:32]; multstate=2; end
unfortunately bit-select , part-select features of verilog part of expression operands. not verilog operators (see sec. 5.2.1 of verilog 2005 std. document, ieee std 1364-2005) , can therefore not applied arbitrary expressions directly registers or wires.
there various ways want recommend using temporary 64 bit variable:
wire [31:0] a, b; reg [63:0] tmp; reg [31:0] ab_lsb, ab_msb; @(posedge clk) begin tmp = a*b; ab_lsb <= tmp[31:0]; ab_msb <= tmp[63:32]; end
(the assignments ab_lsb , ab_msb conditional. otherwise simple "{ab_msb, ab_lsb} <= a*b;" trick of course.)
note i'm using blocking assignment assign 'tmp' need value in following 2 lines. means unsafe access 'tmp' outside block.
also note concatenation hack {a*b} not needed here, a*b assigned 64 bit register. fits recommendation in sec 5.4.1 of ieee std 1364-2005:
multiplication may performed without losing overflow bits assigning result wide enough hold it.
however, said: "the point here don't have access 64 bit register".
so describe solution not use verilog 64 bit registers. not have impact on resulting hardware. different in verilog code.
the idea access msb bits shifting result of a*b. following naive version of not work:
ab_msb <= (a*b) >> 32; // don't -- won't work!
the reason why not work width of a*b determined left hand side of assignment, 32 bits. therefore result of a*b contain lower 32 bits of results.
one way of making bit width of operation self-determined using concatenation operator:
ab_msb <= {a*b} >> 32; // don't -- still won't work!
now result width of multiplication determined using max. width of operands. unfortunately both operands 32 bit , therefore still have 32 bit multiplication. need extend 1 operand 64 bit, e.g. appending zeros (i assume unsigned operands):
ab_msb <= {{32'd0, a}*b} >> 32;
accessing lsb bits easy default behavior anyways:
ab_lsb <= a*b;
so end following alternative code:
wire [31:0] a, b; reg [31:0] ab_lsb, ab_msb; @(posedge clk) begin ab_lsb <= a*b; ab_msb <= {{32'd0, a}*b} >> 32; end
xilinx xst 14.2 generates same rtl netlist both versions. recommend first version easier read , understand. if 'ab_lsb' or 'ab_msb' used, synthesis tool automatically discard unused bits of 'tmp'. there no difference.
if not information looking should clarify why , how "don't have access 64 bit registers". after all, try access bits [63:32] of 64 bit value in code well. can't calculate upper 32 bits of product a*b without performing calculations required lower 32 bits, might asking not possible.
Comments
Post a Comment