Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Verilog array of registers synthesis problem

Status
Not open for further replies.

Dwaipayan

Newbie level 4
Joined
Jul 4, 2011
Messages
6
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,371
I need to add the contents of four registers in an array I have written a code but on synthesizing it creates latches :


`timescale 1ns / 100ps

module regblock0 (sum, Clk, nReset, nReady);

input Clk, nReset, nReady;

output [15:0] sum;
reg [15:0] temp1, temp2;
reg [15:0] sum;
wire Clk;
wire nReset;
wire nReady;

reg [1:0] state;
wire [15:0] data_str0 [0:3];

parameter S0=0,S1=1,S2=2,S3=3;

assign data_str0[0]= 10000;
assign data_str0[1]= 2000;
assign data_str0[2]= 3000;
assign data_str0[3]= 4000;

always @(posedge Clk or negedge nReset)
begin
if (!nReset)
state <= S0;

else
case (state) //checking all the states here

S0: state <= S1;

S1: state <= S2;

S2: state <= S3;

S3: state <= S0;

endcase
end

always @(state)
begin

case(state)

S0 : begin
sum = 0;
temp1 = 0;
temp2 = 0;
end

S1 : temp1 = data_str0[0] + data_str0[1];

S2 : temp2 = temp1 + data_str0[2];

S3 : sum = temp2 + data_str0[3];

endcase

end

endmodule


temp1 and temp2 are the two latches.
which I want to avoid.

I changed the code using 4 input adder :


`timescale 1ns / 100ps

module regblock0 (sum, Clk, nReset);

input Clk, nReset;

output [15:0] sum;
reg [15:0] temp1, temp2;
reg [15:0] sum;
wire Clk;
wire nReset;

reg [1:0] state;
wire [15:0] data_str0 [0:3];

parameter S0=0,S1=1,S2=2,S3=3;

assign data_str0[0]= 10;
assign data_str0[1]= 20;
assign data_str0[2]= 30;
assign data_str0[3]= 40;

always @(posedge Clk or negedge nReset)
begin
if (!nReset)
begin
temp1 <= 0;
temp2 <= 0;
sum <= 0;
end

else
begin
// temp1 <= data_str0[0] + data_str0[1];

// temp2 <= temp1 + data_str0[2];

sum <= data_str0[0] + data_str0[1] + data_str0[2] + data_str0[3];
end

end
endmodule


I am getting the sum in 2 clock cylces rather than 4 but is ist fine to use 4 input adder

can someone suggest me how to add 4 data registers
 

S1 : temp1 = data_str0[0] + data_str0[1];

S2 : temp2 = temp1 + data_str0[2];

S3 : sum = temp2 + data_str0[3];

I think the problem may be because you are using the blocking statements.Blocking statements create latches.So make the temp1,temp2,sum non blocking statements.
S1 : temp1 <= data_str0[0] + data_str0[1];

S2 : temp2 <= temp1 + data_str0[2];

S3 : sum <= temp2 + data_str0[3];

I hope this may solve your problem.
 

- The state machine doesn't seem to serve a reasonable purpose in your design.
- latches are generated by assigning data conditionally to variables in an asynchronous always block
- assuming, that you can't add all four register values in a single clock cycle due to timing restrictions, you can change the second design to a simple pipelined adder, preferable with equal delays

Code:
always @(posedge Clk) 
begin
  temp1 <= data_str0[0] + data_str0[1];
  temp2 <= data_str0[2] + data_str0[3];
  sum <= temp1 + temp2;
end
I think the problem may be because you are using the blocking statements.Blocking statements create latches.So make the temp1,temp2,sum non blocking statements.
You'll discover, that both creates latches in the present asynchronous always block.
 

@ADI :

Can we use non-blocking in the combinational block??

---------- Post added at 12:08 ---------- Previous post was at 12:00 ----------

@FVM :

I have done this but there is a different problem.
Actually I need two register blocks like this the first register block (data_str0) and the second register block (data_str1) and I need to find the sum of both the blocks say sum0 and sum1 and then I need to find cD = sum0 - sum1 and cA = sum0 + sum1, there I am facing a problem.
I will paste the code :

regtop.v :

`timescale 1ns / 100ps

module regtop (cD, cA, Clk, nReset);

input Clk, nReset;

output [15:0] cD;
output [15:0] cA;

wire [15:0] sum0, sum1;
reg [15:0] cD, cA;

wire Clk, nReset;

regblock0 rgb0 (sum0, Clk, nReset);
regblock1 rgb1 (sum1, Clk, nReset);

always @(posedge Clk or negedge nReset)

if (!nReset)
begin
cA <= 0;
cD <= 0;
end

else
begin
cA <= sum0 + sum1;
cD <= sum0 - sum1;
end
//end

endmodule
now if simulate this in modelsim then cD and cA gets calculated for each of the data_str0 and data_str1 values.

for example :

data_str0[0] = 10
data_str0[1] = 20
data_str0[2] = 30
data_str0[3] = 40

data_str1[0] = 1
data_str1[1] = 2
data_str1[2] = 3
data_str1[3] = 4

then basically i should get sum0 = 100
and sum1 = 10
and cD = 90
cA = 110

but if I follow ur method for regblock0 and regblock1 then I am getting the cD and cA for each of the entries
 

The design is still a kind of unreal, without any real input signals, e.g. looking at the regblock instances that supply data from nowhere. These constructs are only valid in simulation and in my view more or less meaningless when discussing real hardware design problems.

My pipelined structure suggestion works well, if the input signals are changing simultaneously, which would be the case in most real designs. Otherwise you should specify the input signal timing. Generally, all registers should be assigned under a clock synchronous always block. Everything else can be changed at will.
 

Thanks it is working.

I would like to know something

say in this design I am specifying the register inputs that is they are fixed and thus mentioned through the 'assign' clause.

What is the way if I want the register contents to be dynamic i.e, I want the data_str contents to be dynamic, how can i use them in verilog module.

Could you give me one example
 

say in this design I am specifying the register inputs that is they are fixed and thus mentioned through the 'assign' clause.
In this case, you won't need no logic design, because all results are known before. At best you get a kind of signal generator.
What is the way if I want the register contents to be dynamic i.e, I want the data_str contents to be dynamic, how can i use them in verilog module.
I would expect input signals to be connected. The question refers to the purpose of your design.
 

I have a code where I have an array of registers mainreg having sixteen registers, I want to consider the first block of 8 registers from 0 - 7 from these 8 i want to separate 2 pairs of register arrays having 4 registers each and then again do the same thing from the next block of 8 registers.

Thus say mainreg has 0 - 15, I will consider the first 8, 0 - 7 and bifurcate them into two registers 'a' having 4 regs and 'b' having four and again the same thing for the next block of 8 registers.

The formula for the bifurcation of 4 registers from a block of 8 registers is as follows :

the block of 8 regs has : 0 1 2 3 4 5 6 7
the first array 'a' will have : 0 3 5 6 (starting from 0 do +3, +2, +1)
the second array 'b' will have : 7 4 2 1 (starting from 7 do -3, -2, -1)

and the again for the next block of 8 regs has : 8 9 10 11 12 13 14 15
'a' will have : 8 11 13 14
'b' will have : 15 12 10 9

thus I have one counter c1 which will count the no of blocks having 8 regs here it is 16/8 = 2 therefore c1 should operate from 0 < 2
for first block of 8 regs c1 = 0
another counter for incrementing 3, 2, 1 starting from 0 finishing at 7
another counter for decrementing 3, 2, 1 starting from 7 finishing at 0

and then for the next block of 8 registers (starting from 8 to 15) c1 = 1
c2 = c2+2 = 8
c3 = c3+14 = 15

I have written the code :

`timescale 1ns / 100ps

module mainreg (clk, nReset);

input clk, nReset;

wire clk;
wire nReset;
parameter n=16;
// S0=0, S1=1, S2=2, S3=3, S4=4;

reg [15:0] c1;
reg [15:0] c2;
reg [15:0] c3;

// integer c1, c2, c3;

// reg [2:0] state;
wire [15:0] mainreg [0:n-1];

reg [15:0] a [0:3];
wire [15:0] b [0:3];

assign mainreg[0]= 0;
assign mainreg[1]= 1;
assign mainreg[2]= 2;
assign mainreg[3]= 3;
assign mainreg[4]= 4;
assign mainreg[5]= 5;
assign mainreg[6]= 6;
assign mainreg[7]= 7;
assign mainreg[8]= 8;
assign mainreg[9]= 9;
assign mainreg[10]= 10;
assign mainreg[11]= 11;
assign mainreg[12]= 12;
assign mainreg[13]= 13;
assign mainreg[14]= 14;
assign mainreg[15]= 15;

always @(posedge clk or negedge nReset)

if (!nReset)
begin
a[0] = 0;
a[1] = 0;
a[2] = 0;
a[3] = 0;

b[0] = 0;
b[1] = 0;
b[2] = 0;
b[3] = 0;

c1 = 0;
c2 = 0;
c3 = 7;
end
else

if (c1 < 2)
begin
a[0] = mainreg[c2];
b[0] = mainreg[c3];
a[1] = 0;
b[1] = 0;
a[2] = 0;
b[2] = 0;
a[3] = 0;
b[3] = 0;

c2 = c2 + 3;
c3 = c3 - 3;

a[1] = mainreg[c2];
b[1] = mainreg[c3];
a[2] = 0;
b[2] = 0;
a[3] = 0;
b[3] = 0;

c2 = c2 + 2;
c3 = c3 - 2;

a[2] = mainreg[c2];
b[2] = mainreg[c3];
a[3] = 0;
b[3] = 0;

c2 = c2 + 1;
c3 = c3 - 1;

a[3] = mainreg[c2];
b[3] = mainreg[c3];

c2 = c2 + 2;
c3 = c3 + 14;
c1 = c1 + 1;
end
else
begin

a[0] = 0;
a[1] = 0;
a[2] = 0;
a[3] = 0;

b[0] = 0;
b[1] = 0;
b[2] = 0;
b[3] = 0;

end

endmodule



It is simulating fine to give two arrays :

a : 0 3 5 6
b : 7 4 2 1

and

a : 8 11 13 14
b : 15 12 10 9


but I am having problems in synthesizing as it says array delacration is oversize in a[0]=manireg[c2];

I have used non-blocking also but it gives wrong result.

I wrote in a state machine format but it synthesis to latches :


`timescale 1ns / 100ps

module mainreg (Clk, nReset);

input Clk, nReset;

wire Clk;
wire nReset;
parameter n=16, S0=0, S1=1, S2=2, S3=3, S4=4;

//reg [15:0] c1, c2, c3;
integer c1, c2, c3;

reg [2:0] state;
wire [15:0] mainreg [0:n-1];

reg [15:0] a [0:3];
reg [15:0] b [0:3];

assign mainreg[0]= 0;
assign mainreg[1]= 1;
assign mainreg[2]= 2;
assign mainreg[3]= 3;
assign mainreg[4]= 4;
assign mainreg[5]= 5;
assign mainreg[6]= 6;
assign mainreg[7]= 7;
assign mainreg[8]= 8;
assign mainreg[9]= 9;
assign mainreg[10]= 10;
assign mainreg[11]= 11;
assign mainreg[12]= 12;
assign mainreg[13]= 13;
assign mainreg[14]= 14;
assign mainreg[15]= 15;

always @(posedge Clk or negedge nReset)

if (!nReset)
state <= S0;
else
begin
if (c1 < 2)
case(state)
S0 : begin

state <= S1;

end
S1 : begin

state <= S2;

end
S2 : begin
state <= S3;

end
S3 : begin
state <= S4;

end
S4 : begin
state <= S1;

end
endcase
end

always @(state,c1,c2,c3)
begin
case(state)

S0 : begin
a[0] = 0;
a[1] = 0;
a[2] = 0;
a[3] = 0;

b[0] = 0;
b[1] = 0;
b[2] = 0;
b[3] = 0;
c1 = 0;
c2 = 0;
c3 = 7;


end
S1 : begin
a[0] = mainreg[c2];
b[0] = mainreg[c3];
a[1] = 0;
b[1] = 0;
a[2] = 0;
b[2] = 0;
a[3] = 0;
b[3] = 0;
c2 = c2 + 3;
c3 = c3 - 3;

end
S2 : begin
a[1] = mainreg[c2];
b[1] = mainreg[c3];
a[2] = 0;
b[2] = 0;
a[3] = 0;
b[3] = 0;
c2 = c2 + 2;
c3 = c3 - 2;

end
S3 : begin
a[2] = mainreg[c2];
b[2] = mainreg[c3];
a[3] = 0;
b[3] = 0;
c2 = c2 + 1;
c3 = c3 - 1;

end
S4 : begin
a[3] = mainreg[c2];
b[3] = mainreg[c3];
c2 = c2 + 2;
c3 = c3 + 14;
c1 = c1 + 1;

end
endcase

end

endmodule
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top