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.

[SOLVED] How to code this in verilog?

Status
Not open for further replies.

hiten09

Member level 2
Member level 2
Joined
Dec 31, 2011
Messages
51
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Visit site
Activity points
1,630
I'm doing some program on multiplier where i need to code multiplier in behavioral style the expression is

multi.jpg

i used nesting of for loop but it stuck during simulation here is the code

Code:
temp=0;
pro=0;
for(i=0;i<8;i=i+1)
begin
    for(j=0;j<8;j=j+1)
 begin
    temp=temp+(a[i]*b[j])&(2**(i+j));
  end
    pro=pro+temp;
end

can anyone please detect the fault:sad: :sad:
 
Last edited by a moderator:

You are thinking of this as a microcontroller. Don't do this, think in hardware. What is the hardware you need to achieve this? Your code is not syntethizable.

You need multipliers. You need to make the sums. And how are you going to make the exp in hardware? It is possible, but you can't just write this as a sequential code.

Also, you need to clock your project. Where is your clock? Learn to pipeline. What you are trying to do is always combinatorial. Start the code by a:

Code:
always @(posedge clk)
begin
end

And try to make make one step in each side. From where do you start? I would start by reading a and b from a memory. For this, you need to infer a memory first. After this, you need to multiply them.
 
The code will synthesize with some minor changes, but like pbenardi says think in hardware. What you have is purely combinatorial code, which will be very slow. Realistically if this is to be synthesized the code should be rewritten with the loops completely unraveled and pipelined (perfomance) and/or an FSM that cycles through the loops using memory/registers to store the intermediate results of each iteration of the loop.

You should note that the following line was incorrect for the intended operation.
Code:
temp=temp+(a[i]*b[j])&(2**(i+j));
The & is a bit wise AND operation not a multiply.

The following code synthesizes and results in a massive combinatorial structure. I haven't verified if it matches the original intent. If you're feeling adventurous you can run the tb I created on both the rtl and the output verilog netlist of the synthesized design.

Modified for synthesis code.

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
module math_loop (
  input [7:0] a,
  input [7:0] b,
  output [31:0] c
);
 
reg [31:0] temp, pro;
integer i,j;
 
initial begin
  temp=0;
  pro=0;
end
 
always @ * begin
  for(i=0;i<8;i=i+1) begin
    for(j=0;j<8;j=j+1) begin
      temp=temp+(a[i]*b[j])*(2**(i+j));
    end
    pro=pro+temp;
  end
end
 
assign c = pro;
 
endmodule



Test bench to force a and b to something

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module tb_math_loop ();
 
reg [7:0] a, b;
wire [15:0] c;
 
test uut (
  .a  (a),
  .b  (b),
  .c  (c)
);
 
initial begin
  a = 8'h93;
  b = 8'hc3;
end
 
endmodule



FYI, I'm not sure if c is large enough to hold all the bits of the result, I just threw in a 32-bit result as I knew it would be larger than the 8-bit inputs after all the iterations.
 
Last edited:
Actually i wanted to implement pipelining only, wave pipelining but i just thought of making basic multiplier first because i dont know much about pipelining. I made the gate level coding but in pipelining we need beh level so i changed it to beh, but its going very big code if i am coding line by line. Ya i didn't thought about hardware, so i have to code keeping in mind what hardware it is going to implement.

Is this correct coding line by line? i mean it will take some 50 to 60 lines as addition as well as multiplication is propagated to next stages, or is there any other way?

i will post my code in next reply,and a big thanks pbenardi and ads-ee for your valuable time and for sharing your knowledge.
 

i made some changes to code of ads-ee, i got the output also but how to implement pipelining in it? If i am not wrong in pipelining we add buffer/D flipflop but here we are doing everything inside always block so how to add a buffer here?

this is the code and testbench




Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
module trial (clk,a,b,c);
  input clk;
  input [7:0] a;
  input [7:0] b;
  output [15:0] c;
reg [15:0] temp, pro;
integer i,j,t,p;
  
initial 
begin
temp=0;
pro=0;
end
 
always @(posedge clk)
begin
pro=0;
for(i=0;i<8;i=i+1)
begin
    for(j=0;j<8;j=j+1) 
    begin
    t=temp+(a[i]*b[j])*(2**(i+j));
    temp=t; 
    end
p=pro+temp;
pro=p;
temp=0;
end  
end
 
assign c = pro;
 
endmodule
 
 
//testbench
 
module trialtest();
 
reg clk;
reg [7:0] x,y;
wire [15:0]c;
 
 
trial f1(clk,x,y,c);
 
initial
clk=1;
 
always
#5 clk=~clk;
 
initial
begin
 
x=8'd42;
y=8'd15;
#10;
 
x=8'd125;
y=8'd2;
 
end
 
endmodule

 
Last edited by a moderator:

in above code i was getting a very big hardware, so i tried another way, i got the output and implemented pipelining in it but i have two doubts :
i> Is this correct way to implement pipelining?
ii> here latency is 3 so what should be the output when inputs are under processing, i am getting random outputs at that time i wrote testbench for two iterations,

here is my code:

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
module asic (clk,q0,q1,c);
  input clk;
  input [7:0] q0;
  input [7:0] q1;
  output [15:0] c;
wire [7:0]a,b;
wire [15:0]c;
wire [15:0] temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8;
wire [15:0] s1,s2,s3,s4,s5,s6,s7;
wire [15:0] p0,p1,p2,p3,p4,p5,p6,p7;
 
 
assign a=q0;
assign b=q1;
 
assign p0= (a[0] * b);
 
assign temp2=(a[1] * b);
assign s1=(temp2<<1);
assign p1=p0+s1;
 
assign temp3=(a[2] * b);
assign s2=(temp3<<2);
delay d2(p1,s2,p2,clk);
 
assign temp4=(a[3] * b);
assign s3=(temp4<<3);
assign p3=p2+s3;
 
assign temp5=(a[4] * b);
assign s4=(temp5<<4);
assign p4=p3+s4;
 
assign temp6=(a[5] * b);
assign s5=(temp6<<5);
delay d5(p4,s5,p5,clk);
 
assign temp7=(a[6] * b);
assign s6=(temp7<<6);
assign p6=p5+s6;
 
assign temp8=(a[7] * b);
assign s7=(temp8<<7);
delay d7(p6,s7,p7,clk);
 
assign c = p7;
 
endmodule
 
 
module delay(op1,op2,add,clk);
  input [15:0]op1,op2;
  output [15:0]add;
  input clk;
  reg [15:0] add;
  
  always @(posedge clk)
  add=op1+op2;
  
endmodule

 
Last edited by a moderator:

Referring to the original behavioral description, pro has to be initialized at the begin of the always block, temp at the begin of the outer loop.

Code:
always @ * begin
  pro = 0;
  for(i=0;i<8;i=i+1) begin
    temp = 0;
    for(j=0;j<8;j=j+1) begin
      temp=temp+(a[i]*b[j])*(2**(i+j));
    end
    pro=pro+temp;
  end
end

Pipelining schemes can't be discussed in detail without a problem specification, I fear. A "wave pipelining scheme" e.g. expects that the input signals have a specific timing.
 
Last edited:

what about above code in data flow? is this correct way ? i am getting output at 3rd and 6th clock pulse, i want the outputs at 3rd and 4th pulse in sequence, what should i change or add in above code ?
 

If the design is fully pipelined then you should get outputs on every clock cycle after an initial latency( i.e. the pipeline depth).
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top