Unfortunately, Verilog's selection and partial selection functions are part of the expression operands. They are not Verilog operators (see Section 5.2.1 Std. Document Verilog 2005, IEEE Std 1364-2005) and therefore cannot be applied to arbitrary expressions, but only directly to registers or wires.
There are various ways to do what you want, but I would recommend using a temporary 64-bit variable:
wire [31:0] A, B; reg [63:0] tmp; reg [31:0] ab_lsb, ab_msb; always @(posedge clk) begin tmp = A*B; ab_lsb <= tmp[31:0]; ab_msb <= tmp[63:32]; end
(The assignments ab_lsb and ab_msb may be conditional. Otherwise, a simple "{ab_msb, ab_lsb} <= A * B;" could also do the trick.)
Note that I use lock assignment to assign 'tmp', as I need a value in the next two lines. It also means that it is not safe to access tmp from the outside, it always blocks.
Also note that concatenational hacking {A * B} is not needed here, since A * B is assigned to a 64-bit register. This also complies with the recommendations in section 5.4.1 of the IEEE Std 1364-2005 standard:
Multiplication can be performed without losing overflow bits by assigning the result to something wide enough to hold it.
However, you said: "The fact is that I do not have access to the 64-bit register."
So, I will describe a solution that does not use Verilog's 64-bit registers. However, this will not affect the final equipment. It will look different Verilog code.
The idea is to access the MSB bits by shifting the result of A * B. The following naive version of this will not work:
ab_msb <= (A*B) >> 32; // Don't do this -- it won't work!
The reason this does not work is because the width of A * B is determined by the left side of the assignment, which is 32 bits. Therefore, the result of A * B will contain only the lower 32 bits of the results.
One way to make a bit of the width of an operation is self-determined using the concatenation operator:
ab_msb <= {A*B} >> 32; // Don't do this -- it still won't work!
Now the width of the multiplication result is determined using max. the width of its operands. Unfortunately, both operands are 32 bits long, and therefore we still have 32 bit multiplication. Therefore, we need to expand one operand to 64 bits, for example. by adding zeros (I accept unsigned operands):
ab_msb <= {{32'd0, A}*B} >> 32;
Accessing the lsb bits is easy, as this is the default behavior:
ab_lsb <= A*B;
So, we get the following alternative code:
wire [31:0] A, B; reg [31:0] ab_lsb, ab_msb; always @(posedge clk) begin ab_lsb <= A*B; ab_msb <= {{32'd0, A}*B} >> 32; end
Xilinx XST 14.2 creates the same RTL connection list for both versions. I highly recommend the first version, as it is much easier to read and understand. If only ab_lsb or ab_msb is used, the synthesis tool automatically discards the unused tmp bits. Therefore there is no difference.
If this is not the information you are looking for, you should probably explain why and how you "do not have access to 64-bit registers." In the end, you are trying to access the bits [63:32] of a 64-bit value in the code. Since you cannot calculate the top 32 bits of the A * B product without doing almost all the calculations necessary for the lower 32 bits, you can ask for something that is impossible.