Verilog: Sum over n register - sum

Im trying to build an moving average module. It should use the number of values to use as parameter.
How do I get the sum of all n tmp-registers using a for- or gernerate-block within one clock-cylce?
reg [WORDLEN - 1:0] tmp [SIZE - 1:0];
reg [WORDLEN + SIZE / 2 - 1:0] sum;
always #(posedge clk)
sum <= sum(tmp) // Like <= tmp[0] + tmp[1] + ... + tmp[SIZE-1]

Loops like this tend to be easier to understand if you first break apart the synchronous and combinatorial parts. First we have a combinatorial loop which unrolls to a configurable number of adds. Then imply a flip-flop on the result.
integer i;
reg [WORDLEN + SIZE / 2 - 1:0] sum_comb;
always #* begin
sum_comb = 'd0;
for( i=0; i< SIZE; i=i+1) begin
sum_comb = sum_comb + tmp[i];
end
end
always #(posedge clk) begin
sum <= sum_comb;
end

If you use SystemVerilog, you can just write:
always #(posedge clk)
sum <= tmp.sum;
Below is a complete sample code:
module test;
parameter WORDLEN = 8;
parameter SIZE = 4;
reg [WORDLEN - 1:0] tmp [SIZE - 1:0];
reg [WORDLEN + SIZE / 2 - 1:0] sum;
logic clk = 0;
initial begin
tmp = '{ '{1}, '{4}, '{6}, '{7}};
forever begin
clk = ~clk;
#10;
tmp [0] = tmp[0] + 1; //Increment tmp[0] twice during each clock for testing
end
end
always #(posedge clk) begin
sum <= tmp.sum ;
$display ("sum(tmp) = sum(%p) = %d", tmp, sum) ;
end
endmodule
output:
# sum(tmp) = sum('{1, 4, 6, 7}) = 18
# sum(tmp) = sum('{1, 4, 6, 9}) = 20
# sum(tmp) = sum('{1, 4, 6, 11}) = 22
# sum(tmp) = sum('{1, 4, 6, 13}) = 24
# sum(tmp) = sum('{1, 4, 6, 15}) = 26
# sum(tmp) = sum('{1, 4, 6, 17}) = 28

Related

Error (10028): Can't resolve multiple constant drivers and Error (10029): Constant driver

I am new to Verilog, and trying to write a traffic light code where the LED light changes after certain time. I'm keep getting on different errors while compiling. I tried to fix them by changing the arrangement, or variables in the code, but it still fails.
This is the code I wrote,
module traffic_light(clk, reset, G1, Y1, R1, G2, Y2, R2);
input clk, reset;
output reg G1, Y1, R1, G2, Y2, R2;
// parameters for each light control
parameter GREEN = 3'b001,
YELLOW = 3'b010,
RED = 3'b100,
LEFT_GREEN = 3'b101, // assume both red and green will be turned on
LEFT_YELLOW = 3'b110; // assume both red and yellow will be turned on
// finite-state definition (Moore Type):
// ---------------------------
// NSlight EWlight
// ---------------------------
parameter S0 = 3'd0, // GREEN RED
S1 = 3'd1, // YELLOW RED
S2 = 3'd2, // RED, GREEN RED
S3 = 3'd3, // RED, YELLOW RED
S4 = 3'd4, // RED GREEN
S5 = 3'd5, // RED YELLOW
S6 = 3'd6, // RED RED, GREEN
S7 = 3'd7; // RED RED, YELLOW
// internal state variables
reg [2:0] state, next_state;
integer t1 = 19, t2 = 4;
integer count;
// buttons are appropriate for use as clock or reset inputs in a circuit
always #(posedge clk, negedge reset)
if(reset == 'b0) // button pressed, when reset is active low
begin
next_state = S0;
count = t1;
end
else
state <= next_state;
always #(next_state)
begin
next_state = S0;
count = t1;
case(state)
S0:
if (count < 0) // load: if the count reaches below 0, reset
begin
count <= t2;
next_state <= S1;
end
else // enable
begin
// down count
count <= count - 1;
// assign LEDs
G1 <= 1;
Y1 <= 0;
R1 <= 0;
G2 <= 0;
Y2 <= 0;
R2 <= 1;
end
S1:
if (count < 0)
begin
count <= t1;
next_state <= S2;
end
else
begin
G1 <= 0;
Y1 <= 1;
R1 <= 0;
G2 <= 0;
Y2 <= 0;
R2 <= 1;
count <= count - 1;
end
S2:
if (count < 0)
begin
count <= t2;
next_state <= S3;
end
else
begin
G1 <= 1;
Y1 <= 0;
R1 <= 1;
G2 <= 0;
Y2 <= 0;
R2 <= 1;
count <= count - 1;
end
S3:
if (count < 0)
begin
count <= t1;
next_state <= S4;
end
else
begin
G1 <= 0;
Y1 <= 1;
R1 <= 1;
G2 <= 0;
Y2 <= 0;
R2 <= 1;
count <= count - 1;
end
S4:
if (count < 0)
begin
count <= t1;
next_state <= S5;
end
else
begin
G1 <= 0;
Y1 <= 0;
R1 <= 1;
G2 <= 1;
Y2 <= 0;
R2 <= 0;
count <= count - 1;
end
S5:
if (count < 0)
begin
count <= t1;
next_state <= S6;
end
else
begin
G1 <= 0;
Y1 <= 0;
R1 <= 1;
G2 <= 0;
Y2 <= 1;
R2 <= 0;
count <= count - 1;
end
S6:
if (count < 0)
begin
count <= t2;
next_state <= S7;
end
else
begin
G1 <= 0;
Y1 <= 0;
R1 <= 1;
G2 <= 1;
Y2 <= 0;
R2 <= 1;
count <= count - 1;
end
S7:
if (count < 0)
begin
count <= t1;
next_state <= S0;
end
else
begin
G1 <= 0;
Y1 <= 0;
R1 <= 1;
G2 <= 0;
Y2 <= 1;
R2 <= 1;
count <= count - 1;
end
endcase
end
endmodule
and these are the errors generated from the above code:
Error (10028): Can't resolve multiple constant drivers for net "next_state.S0" at traffic_light.v(41)
Error (10029): Constant driver at traffic_light.v(32)
Error (10028): Can't resolve multiple constant drivers for net "next_state.S1" at traffic_light.v(41)
Error (10028): Can't resolve multiple constant drivers for net "next_state.S2" at traffic_light.v(41)
Error (10028): Can't resolve multiple constant drivers for net "next_state.S3" at traffic_light.v(41)
Error (10028): Can't resolve multiple constant drivers for net "next_state.S6" at traffic_light.v(41)
Error (10028): Can't resolve multiple constant drivers for net "next_state.S7" at traffic_light.v(41)
Error (12152): Can't elaborate user hierarchy "traffic_light:inst"
Hope I can get any suggestions or solutions to this problem. Thank you in advance.
I solved the problem after few more searching.
Error (10028): Can't resolve multiple constant drivers for net... VHDL ERROR
"Multiple Constant Drivers" Error Verilog with Quartus Prime
These two links helped solving, the problem is that you cannot assign one variable in two different always block.
The below code is the fixed one.
module traffic_light(clk, reset, G1, Y1, R1, G2, Y2, R2, time_);
input clk, reset;
output reg G1, Y1, R1, G2, Y2, R2;
output reg [4:0] time_; // added, it displays the remaining time
// parameters for each light control
parameter GREEN = 3'b001,
YELLOW = 3'b010,
RED = 3'b100,
LEFT_GREEN = 3'b101, // assume both red and green will be turned on
LEFT_YELLOW = 3'b110; // assume both red and yellow will be turned on
// finite-state definition (Moore Type):
// ---------------------------
// NSlight EWlight
// ---------------------------
parameter S0 = 3'd0, // GREEN RED
S1 = 3'd1, // YELLOW RED
S2 = 3'd2, // RED, GREEN RED
S3 = 3'd3, // RED, YELLOW RED
S4 = 3'd4, // RED GREEN
S5 = 3'd5, // RED YELLOW
S6 = 3'd6, // RED RED, GREEN
S7 = 3'd7; // RED RED, YELLOW
// internal state variables and time settings
reg [2:0] state, next_state;
integer t1 = 19, t2 = 4;
reg count; // changed to count only
always #(posedge clk)
if(reset == 0) // button pressed, when reset is active low
begin
state <= S0;
time_ <= t1;
end
else
begin
state <= next_state;
time_ <= count;
end
always #(*) // changed according to advice in the comment
case(state)
S0: if (count < 0) // load: if the count reaches below 0, reset
begin
count <= t2;
next_state <= S1;
end
else // enable
begin
// down count
count <= count - 1;
// assign LEDs
G1 <= 1;
Y1 <= 0;
R1 <= 0;
G2 <= 0;
Y2 <= 0;
R2 <= 1;
end
S1: if (count < 0)
begin
count <= t1;
next_state <= S2;
end
else
begin
G1 <= 0;
Y1 <= 1;
R1 <= 0;
G2 <= 0;
Y2 <= 0;
R2 <= 1;
count <= count - 1;
end
S2: if (count < 0)
begin
count <= t2;
next_state <= S3;
end
else
begin
G1 <= 1;
Y1 <= 0;
R1 <= 1;
G2 <= 0;
Y2 <= 0;
R2 <= 1;
count <= count - 1;
end
S3: if (count < 0)
begin
count <= t1;
next_state <= S4;
end
else
begin
G1 <= 0;
Y1 <= 1;
R1 <= 1;
G2 <= 0;
Y2 <= 0;
R2 <= 1;
count <= count - 1;
end
S4: if (count < 0)
begin
count <= t2;
next_state <= S5;
end
else
begin
G1 <= 0;
Y1 <= 0;
R1 <= 1;
G2 <= 1;
Y2 <= 0;
R2 <= 0;
count <= count - 1;
end
S5: if (count < 0)
begin
count <= t1;
next_state <= S6;
end
else
begin
G1 <= 0;
Y1 <= 0;
R1 <= 1;
G2 <= 0;
Y2 <= 1;
R2 <= 0;
count <= count - 1;
end
S6: if (count < 0)
begin
count <= t2;
next_state <= S7;
end
else
begin
G1 <= 0;
Y1 <= 0;
R1 <= 1;
G2 <= 1;
Y2 <= 0;
R2 <= 1;
count <= count - 1;
end
S7: if (count < 0)
begin
count <= t1;
next_state <= S0;
end
else
begin
G1 <= 0;
Y1 <= 0;
R1 <= 1;
G2 <= 0;
Y2 <= 1;
R2 <= 1;
count <= count - 1;
end
default:
begin
next_state <= S0;
count <= t1;
end
endcase
endmodule
You have next_state assigned in both processes, and that is causing troubles. We can find it actually described in the Verilog Standard. section 14.5 Driving wired logic
Module path output nets shall not have more than one driver within the module. Therefore, wired logic is not allowed at module path outputs
And it also provides an example:

Strange RTL output

[Yosys 0.8]
A colleague of mine threw some random verilog code to Yosys to see how it reacts.
Here it is:
module top(input clk, input led, output led2, output to_port1,output [24:0] to_port2);
reg ctr = 0;
reg[24:0] counter = 2;
always#(posedge clk) begin
if (ctr == 1) begin
ctr <= 0;
counter <= counter + 1;
end
else
ctr <= 1;
end
assign led2 = ctr;
assign to_port1 = led;
assign to_port2 = counter;
endmodule
and Yosys, with command yosys -o synth.v x.v throws:
module top(clk, led, led2, to_port1, to_port2);
reg [24:0] _0_;
reg _1_;
reg [24:0] _2_;
reg _3_;
wire [31:0] _4_;
wire _5_;
input clk;
reg [24:0] counter;
reg ctr;
input led;
output led2;
output to_port1;
output [24:0] to_port2;
assign _4_ = counter + 32'd1;
assign _5_ = ctr == 32'd1;
always #* begin
_3_ = 1'h0;
end
always #* begin
end
always #({ }) begin
ctr <= _3_;
end
always #* begin
_2_ = 25'h0000002;
end
always #* begin
end
always #({ }) begin
counter <= _2_;
end
always #* begin
_1_ = ctr;
_0_ = counter;
casez (_5_)
1'h1:
begin
_1_ = 1'h0;
_0_ = _4_[24:0];
end
default:
_1_ = 1'h1;
endcase
end
always #(posedge clk) begin
ctr <= _1_;
counter <= _0_;
end
assign led2 = ctr;
assign to_port1 = led;
assign to_port2 = counter;
endmodule
Some constructs end up being complicated. This result code above cannot be compiled by recent verilog compilers when the original can.
Why the always #({ }) begin construct and empty always #* begin?
Is there an option we missed?
Thanks
In general you should always run proc (-p proc) between reading and writing Verilog, due to the nature of Yosys' internal representation of the read-in Verilog

How to derive a Fixed Length Output signal from a variable length Input signal in verilog

I have an HDL Block in which the output follows the input in such a way that when input signal is binary 0, output remains 0 but when input turns 1, output turns 1 for a preset number of clock cycles (signal_length). i.e. input may remain high for suppose 65 or 66 clock cycles but output should remain high for preset number of clock cycles. I tried to accomplish the task with Verilog. But I am having an error and I don’t know how to rectify. Hope someone can help.
module last_ind
#(
parameter MAX_LENGTH = 262144,
parameter signal_length
)
(
input clk,
input [17:0] pkt_length,
input tdata,
output tlast
);
reg [17:0] cnt = 0;
always # (posedge clk)
begin
if ((tdata==1) && (cnt<signal_length))
tlast <= 1;
else
cnt <= 0;
end
assign cnt <= cnt + 1'b1;
endmodule
maybe something like this will do. It should keep the signal up for the signal_length cycles and will reset when tdata gets '0'. You decide on the correct protocol though.
reg [17:0] cnt = signal_length;
always # (posedge clk) begin
if (cnt < signal_lenth)
cnt <= cnt + 1;
else if (cnt == signal_length + 1 && tdata == 1 && tlast == 0) begin
cnt <= 0;
tlast <= 1;
end
else if (tdata == 0) begin
cnt <= sighal_length + 1;
tlast <= 0;
end
else
tlast <= 0;
end

VHDL Syntax error in user defined package RNG for genetic algorithm in line number 5

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
Type arr is array (1 to mut_bits) of integer;
type chrom_matrix is array (1 to pop_size) of std_logic_vector(1 to n_comp);
type fitness_arr is array (1 to pop_size) of integer range 0 to 1000;
--type fitness_arr1 is array(1 to pop_size) of real;
type adj_matrix is array (1 to n_comp,1 to n_comp) of bit;
function evalfnc (signal chromosome: in std_logic_vector(1 to 8); signal cut_info:adj_matrix) return integer;
procedure randg (variable x,y,t:in integer range 0 to 1000; variable z: out integer);
procedure convert_bit(variable a:in integer;variable y:out std_logic_vector(8 downto 1));
end rng;
package body rng is
procedure randg (variable x,y,t:in integer range 0 to 1000; variable z: out integer) is
variable val, a:integer range 0 to 1000:= 0;
begin
if x>y then
a:= x-y;
else
a:= y-x;
end if;
if t > 3*a then
val:= (t-a)/2;
elsif t > a then
val:= t-a;
else
val:= (x+y+t)/2;
end if;
z:= val;
end randg;
function evalfnc (signal chromosome: in std_logic_vector(1 to 8); signal cut_info:adj_matrix) return integer is
variable fitness: integer range 0 to 500:= 0;
variable cut_val: integer range 0 to 15:= 0;
variable max_fit:integer range 0 to 360:=100;
begin
for i in 1 to n_comp loop
for j in 1 to n_comp loop
if cut_info(i,j)= ‘1’ then
cut_val:= cut_val +1;
end if;
end loop;
end loop;
fitness := max_fit - cut_val;
return fitness;
end evalfnc;
procedure convert_bit(variable a:in integer ; variable y:out std_logic_vector(8 downto 1)) is
variable no:std_logic_vector(8 downto 1):=”00000000”;
variable num: integer range 0 to 256;
begin
num:= a;
if num <= 255 and num>= 128 then
no(8):=’1’;
num:=num - 128;
end if;
if num < 128 and num >= 64 then
no(7):=’1’;
num:=num - 64;
end if;
if num < 64 and num >= 32 then
no(6):=’1’;
num:=num −32;
end if;
if num < 32 and num >= 16 then
no(5):=’1’;
num:=num - 16;
end if;
if num < 16 and num >= 8 then
no(4):=’1’;
num:=num - 8;
end if;
if num < 8 and num >= 4 then
no(3):=’1’;
num:=num - 4;
end if;
if num < 4 and num >= 2 then
no(2):=’1’;
num:=num - 2;
end if;
if num < 2 then
no(1):=’1’;
end if;
y:= no;
end convert_bit;
end rng;
Line 5 should read package rng is.

Fibonacci shift register pseudo-random number generator

I am attempting to get the following code working for a Fibonacci shift register to generate pseudo-random numbers. Can't seem to get it working, so is(are) there any obvious issues(?)
Shared Function Main() As Integer
Dim start_state As UShort = &HACE1UI ' Any nonzero start state will work.
Dim lfsr As UShort = start_state
Dim bit As UInteger
Dim period As UInteger = 0
Do While lfsr <> start_state
' taps: 16 14 13 11; feedback polynomial: x^16 + x^14 + x^13 + x^11 + 1
bit = ((lfsr >> 0) Xor (lfsr >> 2) Xor (lfsr >> 3) Xor (lfsr >> 5)) And 1
lfsr = (lfsr >> 1) Or (bit << 15)
period += 1
Loop
Return 0
End Function
Last, does "period" need to be divided by a large integer to get U(0,1)'s?
Below is the original C++ code:
# include <stdint.h>
int main(void)
{
uint16_t start_state = 0xACE1u; /* Any nonzero start state will work. */
uint16_t lfsr = start_state;
uint16_t bit; /* Must be 16bit to allow bit<<15 later in the code */
unsigned period = 0;
do
{
/* taps: 16 14 13 11; feedback polynomial: x^16 + x^14 + x^13 + x^11 + 1 */
bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1;
lfsr = (lfsr >> 1) | (bit << 15);
++period;
} while (lfsr != start_state);
return 0;
}
As in #dummy's comment,
Do While lfsr <> start_state
...
Loop
doesn't run because lfsr = start_state at the beginning.
The code equivalent to C++
do {
...
} while (lfsr != start_state);
in VB.NET is
Do
...
Loop While lfsr <> start_state