Verilog: part-select or indexed part-select cannot be applied to memory - verilog

In Verilog:
For an array reg queue[3:0] = 4'b1010; I can do queue <= {queue[0], queue[3:1]};
However, when it comes to 2d array reg [1:0] queue [3:0];, error reported when I do the same thing to it queue <= {queue[0], queue[3:1]};. "part-slect or indexed part-slect cannot be applied to memory"
Therefore, I only do it in a stupid way:
queue[0] <= queue[1];
queue[1] <= queue[2];
queue[2] <= queue[3];
queue[3] <= queue[0];
Is there a better way to do this, like only one sentence.
Thx!

You can always use for loop to do that:
queue[3] = queue[0];
for(i = 2; i >= 0; i = i - 1) begin
queue[i] = queue[i+1];
end

Related

Bits Not Shifting

I want to be able to create a shift from right to left everytime I press a button, but my simulation says my bits is not shifting.
this is the code I wrote:
module Sipo(KEY0, qIN, qOUT, LEDsipo);
input KEY0;
output reg [5:0] qIN;
output reg [5:0] qOUT;
output [6:0] LEDsipo;
assign LEDsipo[0] = qIN[0];
assign LEDsipo[1] = qIN[1];
assign LEDsipo[2] = qIN[2];
assign LEDsipo[3] = qIN[3];
assign LEDsipo[4] = qIN[4];
assign LEDsipo[5] = qIN[5];
assign LEDsipo[6] = KEY0;
always #(KEY0) begin
if (KEY0 == 1)
qIN = 6'b000000;
qOUT[0] <= KEY0;
qOUT[1] <= qOUT[0];
qOUT[2] <= qOUT[1];
qOUT[3] <= qOUT[2];
qOUT[4] <= qOUT[3];
qOUT[5] <= qOUT[4];
if (qOUT == 7'b111111)
qOUT[0] = 0;
qOUT[1] = 0;
qOUT[2] = 0;
qOUT[3] = 0;
qOUT[4] = 0;
qOUT[5] = 0;
qIN = qOUT;
end
endmodule
The result I got in the simulation is that LEDsipo[0] was responding to KEY0, but the rest of the LEDsipo was not. I don't see why my bits are not shifting.
It is dificult to test your code without a testbench, which you have not provided, but I thik that you rissue is an extra exposure to python.
Verilog does not understand indentation as scope indicators and requires begin/end to indicats scopes. So, my guess is that you have at least several issues:
missing begin/end: if (KEY0 == 1) begin...end
incorrect mix of non-blocing/non-blocking assignments mix
Incorrect coding of your latch
bad use of veriog syntax
so, though it is corret, you can avoid using separate bits:
assign LEDsipo[6:0] = {KEY0, qIN[5:0]};
do not use sensititivity lists in the latch, it will not synthesize correctly in your case. Use always #* instead. Well, and begin/end.
I do not know why you need qIn, but it makes no sense to initialize it to 0 in the first place. Also, it is not a part of the latch and should be moved out of the always block.
always #* begin
if (KEY0 == 1) begin // need begin/end for multiple statements
// qIN <= 6'b000000; -- why do you need it?
qOut[5:0] <= {qOut[4:0], KEY0};
if (qOUT == 7'b111111) // can omit begin/end for a single statement
qOut <= 6'b0;
end
end
assign qIn = qOut;
Since you have not provide any testbench, I did not test the code.

System Verilog Loops

Im currently working on the Shift-Add Algorithm (32x32 bit Multiplication) in System Verilog. System Verilog cant find any error and my code is working correctly according to GTKwave. When I synthesize my circuit with yosys, Latches will be added. And that is the Problem. I dont want Latches in my Circuit. Heres my Code:
module multiplier(
input logic clk_i,
input logic rst_i,
input logic start_i,
input logic [31:0] a_i,
input logic [31:0] b_i,
output logic finished_o,
output logic [63:0] result_o
);
typedef enum logic [1:0] { STATE_A, STATE_B} state_t;
state_t state_p, state_n;
logic [63:0] fin_res;
logic [63:0] tmp;
logic rst_flag;
integer i;
always #(posedge clk_i or posedge rst_i) begin
if (rst_i == 1'b1) begin
state_p <= STATE_B;
end
else begin
state_p <= state_n;
end
end
always #(*)begin
state_n = state_p;
case (state_p)
STATE_A: if (start_i == 0) state_n = STATE_B;
STATE_B: if (start_i == 1) state_n = STATE_A;
default: state_n = state_p;
endcase
end
always #(*) begin
case (state_p)
STATE_A: begin
rst_flag = 1;
fin_res = 0;
finished_o = 0;
tmp = 0;
for (i = 0; i < 32; i = i + 1) begin
if (a_i[i] == 1'b1) begin
tmp = b_i;
tmp = tmp << i;
fin_res = fin_res + tmp;
end
end
end
STATE_B: begin
result_o = fin_res;
if (rst_flag == 1) finished_o = 1;
if (start_i == 1) finished_o = 0;
end
default: begin
finished_o = 0;
result_o = 0;
end
endcase
end
endmodule
After spending 2 days only with debugging and not finding any mistake I would like to ask if u could help me. I am assigning every output (at least I think so). So where is my mistake? Is it the for loop? But what would be wrong with it? Thanks in advance for your help :)
Some useful Information for the Code-Snippet: start_i is the starting signal. If this is set to 1 the multiplication should be started. finished_o is the finish flag. If this is set to 1 the CPU will know that the computation is completed. a_i and b_i are the inputs which should be multiplied. result_o is the result of the multiplication which can be read when finished_o is set to 1.
According to yosys i get the following latches:
64 DLATCH_N
64 DLATCH_P
I think something may be wrong with fin_res in the for loop cause that logic variable is exactly 64 bits long as are the Latches
From the comment you have a bunch of variables which are not assigned in the second case statement causing synthesis to generate latches. To avoid it you need to assign all the vars in all branches of the case statement and conditional statements recursively.
However, if there is a default value you can assign to all of them, you can use a pattern similar to the one from the second always block, just assigning default values before the 'case' statement. This way you do not even need the default clause and you can get rid of it in the second always block as well.
always #(*) begin
// set default values
rst_flag = 0;
fin_res = 0;
finished_o = 0;
tmp = 0;
result_o = 0;
case (state_p)
STATE_A: begin
rst_flag = 1;
for (i = 0; i < 32; i = i + 1) begin
if (a_i[i] == 1'b1) begin
tmp = b_i;
tmp = tmp << i;
fin_res = fin_res + tmp;
end
end
end
STATE_B: begin
result_o = fin_res;
// are you sure that you do not need a latch here?
if (rst_flag == 1) finished_o = 1;
if (start_i == 1) finished_o = 0;
end
// you do not need 'default' here.
endcase
end
My fixes will cause combinational behavior and should get rid of latches in synthesis, but it does not look like they will behave as you expected. It looks like you really need a latches here.
rst_flag must be a latch. You set it in STATE_A and use it in STATE_B. It has to keep the value between states. This is a latch behavior.
In STATE_B you change finished_o only if some of conditions met. What happens if the rst_flag and start_i are both 0. do you want finished_o to be 0 or the previous value? In the latter case you need a latch.
How about fin_res ? What do you want to do with it in other states? keep previous value (latch) or have a default value (no latch).
...

How to assign variable pins to a port in verilog?

I have a 32-bit input port pins and a 32-bit input enable pin_en, and want to generate a 16-bit output selected by the enables. I wrote verilog like this, but seems there are some errors.
How can I fix it or any other way to achive? Thanks!
ps: No more than 16 pins selected by en, but maybe less.
input [31:0] pins;
input [31:0] pin_en;
output [15:0] actual_pins;
generate
genvar i;
localparam cnt = 0;
for(i = 0; (i < 'd32) & (cnt < 'd16); i = i + 'd1) begin : b1
if(pin_en[i]) begin
assign actual_pins[i] = pins[cnt];
cnt = cnt + 'd1;
end
end
if(cnt < 16)
assign actual_pins[16 : cnt] = 'b0;
endgenerate
I think that there are several errors in you code:
in generate blocks you cannot do any generation, based on the actual values of variables. The blocks are for the constant expressions only which could be resolved at compilation time, not at the run time. Also, you cannot modify anything in the generated blocks besides genvars. Paremeters (localparams) cannot be modified, so the cnt = cnt + 1 is just illegal there.
you messed up actual_pins and pins. by logic there should be actual_pins[cnt];
you use binary & operator, but you should have used logical && instead.
So, all your code should have been implemented in a run-time constructs, i.e., always blocks. You also need a trigger which will cause the always block to be evaluated. I created a small example where the always block is to be triggered by a clock.
module top (
input clk,
input [31:0] pins,
input [31:0] pin_en,
output reg [15:0] actual_pins
);
always #(posedge clk) begin
int cnt = 0;
int i;
for(i = 0; (i < 'd32) && (cnt < 'd16); i = i + 'd1) begin
if(pin_en[i]) begin
actual_pins[cnt] = pins[i];
cnt = cnt + 'd1;
end
end
for(; cnt < 16; cnt = cnt + 1)
actual_pins[j] = 1'b0;
end
endmodule

How to create bit ranges with terms defined as logic

I understand the following code will not compile, but is there something similar that compiles?
logic [7:0] complete_set, partial_set;
logic [2:0] msb_bit, lsb_bit;
always_comb complete_set = <driven by a logic equation>;
always_comb msb_bit = <driven by a logic equation>;
always_comb lsb_bit = <driven by a logic equation>;
always_comb partial_set[msb_bit:lsb_bit] = complete_set[msb_bit:lsb_bit];
You could do some bitwise decisions like this. I just assumed you would want to set the other bits to zero, but you could also set it to don't cares (1'bx).
for(i = 0; i < 8; i = i + 1) begin
partial_set[i] = (i < lsb_bit) || (i > msb_bit) ? 1'b0 : complete_set[i];
end
Assuming you want the unspecified bits to be 0, you can do this in one line:
always_comb partial_set = complete_set & (2**(msb_bit+1-lsb_bit)-1)<<lsb_bit;
But I think a for loop would be much easer for someone else to understand
always_comb begin
partial_set = '0; // or whatever the unspecified bits should be
for(int ii = lsb_bit; ii <= msb_bit; ii++)
partial_set[ii] = complete_set[ii]
end

RGB value manipulation not working as intended (Verilog)

I am writing code for an entity that takes in RGB values, averages them, then outputs the altered data.
My code looks like this:
module RGBAVG (
input clk,
input rst_n,
input [9:0] iVGA_R,
input [9:0] iVGA_G,
input [9:0] iVGA_B,
output reg [9:0] oVGA_R,
output reg [9:0] oVGA_G,
output reg [9:0] oVGA_B
);
integer avg;
integer count;
integer sum;
initial begin
count = 0;
sum = 0;
avg = 0;
end
always#(posedge clk or negedge rst_n) begin
if (!rst_n) begin //reset
sum = 0;
count = 0;
oVGA_R <= {10{1'b0}};
oVGA_G <= {10{1'b0}};
oVGA_B <= {10{1'b0}};
end
else begin //get RGB values from pixel, prepare for next avg evaluation
count = (count + 1)%307200; //640*480 = 307200
sum = sum + (iVGA_R + iVGA_G + iVGA_B)/3;
if (count == 0) begin
avg = sum/307200; //update avg
sum = 0;
end
oVGA_R <= avg;
oVGA_G <= avg;
oVGA_B <= avg;
end
end
endmodule
However, when I upload the code, all I get is a black screen. What am I doing wrong?
When you say 'compile', do you mean synthesize for a specific target? Are you trying to simulate this, or load it onto an FPGA?
I cannot say exactly what that error means, though I might make a suggestions that may make it go away.
Your logic is somewhat strange to me and probably not synthesizeable. You have an asynchronous reset to your always block, and you're saying that:
Anytime I assert this asynchronous reset, increment the value of count and sum
This kind of construct does not really exist in typical hardware, your asynchronous reset should do only one thing, which is to reset the state of all your flops. Therefore I recommend to move all this:
count = (count + 1)%307200;
sum = sum + (iVGA_R + iVGA_G + iVGA_B)/3;
if (count == 0) begin
avg = sum/307200;
sum = 0;
end
into the else clause so that it doesn't try to write new register values on asynchronous reset. I suspect that this has something to do with your error. You probably want to reset the count and sum as well on reset, is my guess.

Resources