Verilog right shift help - Page 1
Forum section: electronics / general

author: knight
author_rank: Regular Contributor
timestamp: July 06, 2022, 06:47:58 am
content: The following code statement is used for a right shift:Code:x[k+1] <= x + {{k{y}},y[N:k]}; /* >> k */It translates to something like:Code:x[k+1] <= x + ((y) >> y[N:k]);But the above gives a wrong output.This:Code:x[k+1] <= x + (y >> k);gives a slightly wrong output. Can someone help translate the statement?Thanks.

author: hamster_nz
author_rank: Super Contributor
timestamp: July 06, 2022, 07:50:09 am
content: My verilog is poor but here goes....Code:x[k+1] <= x + {{k{y}},y[N:k]}; /* >> k */Let's space it out a bitCode:x[k+1] <= x + { {k{y}} , y[N:k] };Let's replace y with "my_var," to make things clearerCode:x[k+1] <= x + { {k{my_var}} , my_var[N:k] };So to me it says....- take bit 'N' of 'my_var' and repeat it 'k' timesCode:k{my_var}}- also take the bits of 'my_var', from 'N' down to 'k'Code:my_var[N:k]- join them together to make a new N-bit long valueCode:{ {k{my_var}} , my_var[N:k] };Most likely bug is using the wrong number for 'N' (confusing the index of the top-most bit with the number of bits). Maybe it should beCode:x[k+1] <= x + { {k{y[N-1]}} , y[N-1:k] };But just guessing - as I said, my Verilog skills is very poor.

author: knight
author_rank: Regular Contributor
timestamp: July 06, 2022, 09:45:05 am
content: I was learning Verilog and looking at different CORDIC modules and came across this one.Code:module cordic(clk, phase_i, sin_o, cos_o);parameter DW = 16; /* Data width */parameter PIPE_DEPTH = 14; /* Pipeline depth */parameter limP = 16'h4dba; /* P = 0.607253 * 2^15 */input clk;input [DW-1:0] phase_i; /* Phase */output [DW:0] sin_o, cos_o; /* Function value output */reg [DW:0] cos_r=0, sin_o_r=0;reg [DW:0] x[PIPE_DEPTH:0];reg [DW:0] y[PIPE_DEPTH:0];reg [DW:0] z[PIPE_DEPTH:0];wire [DW:0] atan_rom [PIPE_DEPTH:0];reg [1:0] quadrant [PIPE_DEPTH:0];/*integer i;initialbeginfor(i=0; i<=PIPE_DEPTH; i=i+1)beginx = 0; y = 0; z = 0;quadrant = 2'b0;endend*/assign atan_rom = 8189;assign atan_rom = 4834;assign atan_rom = 2554;assign atan_rom = 1296;assign atan_rom = 650;assign atan_rom = 325;assign atan_rom = 162;assign atan_rom = 81;assign atan_rom = 40;assign atan_rom = 20;assign atan_rom = 10;assign atan_rom = 5;assign atan_rom = 2;assign atan_rom = 1;// ================= //// Pipeline stages //// ================= //always @(posedge clk) // stage 0beginx <= {1'b0, limP};y <= 0;z <= {3'b0, phase_i[DW-1-2:0]}; // control the phase_i to the range[0-Pi/2]endalways @(posedge clk) // stage 1beginx <= x - y;y <= x + y;z <= z - atan_rom; // reversal 45degendgenerategenvar k;for(k=1; k<PIPE_DEPTH; k=k+1)beginalways @(posedge clk)beginif (z) begin /* the diff is negative on clockwise */// x[k+1] <= x + {{k{y}},y[DW:k]}; /* >> k */// y[k+1] <= y - {{k{x}},x[DW:k]}; /* >> k */// The above line can be written as x[k+1] <= x + (y >> (k)); (similarly, for all such lines below) in my opinion but I get weird// Sine/Cosine output at the peaks.// Have a look at attached output.x[k+1] <= x + (y >> (k));y[k+1] <= y - (x >> (k));z[k+1] <= z + atan_rom;endelsebegin// x[k+1] <= x - {{k{y}},y[DW:k]};// y[k+1] <= y + {{k{x}},x[DW:k]};x[k+1] <= x - (y >> (k));y[k+1] <= y + (x >> (k));z[k+1] <= z - atan_rom;endendendendgenerate// ================= //// Count quadrant //// ================= //always @(posedge clk)beginquadrant <= phase_i[DW-1:DW-2];endgenerategenvar j;for(j=0; j<PIPE_DEPTH; j=j+1)beginalways @ (posedge clk)beginquadrant[j+1] <= quadrant;endendendgenerate// ================= //// Adjust quadrant //// ================= //always @(posedge clk)case(quadrant)2'b00: begincos_r <= x; /* cos */sin_o_r <= y; /* sin */end2'b01: begincos_r <= ~(y) + 1'b1; /* -sin */sin_o_r <= x; /* cos */end2'b10: begincos_r <= ~(x) + 1'b1; /* -cos */sin_o_r <= ~(y) + 1'b1; /* -sin */end2'b11: begincos_r <= y; /* sin */sin_o_r <= ~(x) + 1'b1; /* -cos */endendcaseassign cos_o = cos_r;assign sin_o = sin_o_r;endmodule

author: BrianHG
author_rank: Super Contributor
timestamp: July 06, 2022, 11:58:32 am
content: Quote from: knight on July 06, 2022, 06:47:58 amHow is the output wrong?What do you expect to happen?What is it you are trying to do?Once again, as you have posted this before, try reading everything including the comments in my final translated cordic code from this post:https://www.eevblog.com/forum/fpga/vhdl-code-to-verilog-code/msg4129336/#msg4129336Just global replace all the integer 'i' with 'k'.

author: radiolistener
author_rank: Super Contributor
timestamp: July 06, 2022, 12:14:08 pm
content: Quote from: knight on July 06, 2022, 06:47:58 amWhat do you mean when you're talking about "right shift"?If you're mean bitwise right shift operation, then it's not clear - for what reason you're using + operation?Is it what you're looking for?Code:x <= x >> k;

author: Nominal Animal
author_rank: Super Contributor
timestamp: July 08, 2022, 07:13:10 pm
content: There are two right shift operations:binaryright shift, which sets the most significant bits zero, andarithmeticright shift, which copies the original most significant bits to the most significant bits.HGFEDCBA ≫ 3 == 000HGFED(binary)HGFEDCBA ⋙ 3 == HHHHGFED(arithmetic)There is also a third related operation,rotationright, which uses either the dropped bits (this being the typical case), or in a multi-word shift case, the least significant bits of some other source for the new most significant bits.HGFEDCBA ≷ 3 == CBAHGFED(binary)Within the sameN-bit word, rotation right byKbits is the same as rotation left byN-Kbits. The two differ, when the rotation takes the new bits from some other source.(Sign extension fromK-bit toN-bit word is copying theKth bit to all bitsi,K<i≤N. It can be a surprisingly useful operation if one can specifyKas a parameter, in an instruction set that deals with different sized units and fixed-point numbers.)Apologies, but I don't know how the three are expressed in Verilog.The three glyphs I used (≫⋙≷) are not any standard representation either, just intuitive ones.

author: BrianHG
author_rank: Super Contributor
timestamp: July 08, 2022, 10:25:12 pm
content: Quote from: Nominal Animal on July 08, 2022, 07:13:10 pmYou got them right.In verilog, it's >> or >>> , << or <<< .I do not know of a rotate without using ' or 'ing the new top & bottom of a shifted reg.

author: radiolistener
author_rank: Super Contributor
timestamp: July 09, 2022, 12:48:46 am
content: Quote from: Nominal Animal on July 08, 2022, 07:13:10 pmin verilog you can do it with >> operator, for example:always @(posedge clock)x <= x >> 3;Quote from: Nominal Animal on July 08, 2022, 07:13:10 pmin verilog you can do it with >>> operator, for example:always @(posedge clock)x <= x >>> 3;Quote from: Nominal Animal on July 08, 2022, 07:13:10 pmI don't know if verilog has such operator, but you can do it in the following way:Code:parameter WIDTH = 16;logic [WIDTH-1:0] x;always @(posedge clock)x <= { x[2:0], x[WIDTH-1:3] };

author: BrianHG
author_rank: Super Contributor
timestamp: July 09, 2022, 12:54:09 am
content: Quote from: radiolistener on July 09, 2022, 12:48:46 amDynamic integer rotations like this are not allowed, however, your fixed shift example is.Rotations with a dynamic shift need to be done like this example:Code:parameter WIDTH = 16;input [3:0] bits_to_rotate;logic [WIDTH-1:0] x;always @(posedge clock)x <= (x << bits_to_rotate) | (x >> (WIDTH - bits_to_rotate));