0
\$\begingroup\$

I am relatively new to verilog, please help with this issue I am having.

Attached is a snippet of the code I am working on. The issue I am facing is, the regs - del1 and del2 are not correctly passing their values when used inside the "always @ " instruction set.

module pwm(clk,en,duty_cycle, switch, out, out1, out2, out3, pulT, pul1T, pul2T, pul3T, pulB, pul1B, pul2B, pul3B, ENABLE, sel, selo);  
input clk;  
input en;   
input ENABLE;
input switch;   
input [7:0]duty_cycle;  
output reg out; 
output reg out1;    
output reg out2;    
output reg out3;    
output reg pulT;   // 
output reg pul1T;  // 
output reg pul2T;  // 
output reg pul3T;  // 
output reg pulB;   // 
output reg pul1B;  // 
output reg pul2B;  // 
output reg pul3B;  //   
output reg sel; 
output wire selo; 

reg seloop;  //Q3   
reg seloon;  //Q4   
reg selop;   //Q1   
reg selon;   //Q2   

reg [7:0]counter;   
reg [7:0]next_counter;  
reg [8:0]ctr12; 
reg [8:0]next_ctr12;    
reg [8:0]ctr34; 
reg [8:0]next_ctr34;    
reg shift;  

reg del1;
reg del2;
parameter dt = 30;
parameter d11 = 60;
parameter d21 = 80;
parameter d12 = 110;
parameter d22 = 130;
parameter mp = 65;

clk_div2 u1 (.clk(clk), .clk_div2(clk_div2));   
assign selo = clk;  

always @ *
begin
case(switch)
1:  begin del1 <= d11; del2 <= d21; end
0: begin del1 <= d21; del2 <= d22; end
endcase
end 

always @ (posedge clk_div2) 
begin       
ctr12 = next_ctr12; 
ctr34 = next_ctr34; 
// --- Set -1 outputs --- //    
if (counter >= 255) begin   
sel <= ~sel;    
end 
// ---- S 1 & 2 -------//   
if (ctr12 <=(del1-dt)) begin //if (ctr34 <=(shift-dt)) begin    
selop = 0;  
selon = 1;  
end 
else if (ctr12 >(del1-dt) && ctr12 <= (del1+dt)) begin //else if (ctr34 >(shift-dt) && ctr34 <= (shift+dt)) begin   
selop = 0;  
selon = 0;  
end 
else if (ctr12 >(del1+dt) && ctr12 <= (del1+256-dt)) begin //else if (ctr34 >(shift+dt) && ctr34 <= (shift+256-dt)) begin   
selop = 1;  
selon = 0;  
end 
else if (ctr12 >(del1+256-dt) && ctr12 <= (del1+256+dt)) begin  //else if (ctr34 >(shift+256-dt) && ctr34 <= (shift+256+dt)) begin  
selop = 0;  
selon = 0;  
end 
else if (ctr12 >(del1+256+dt) && ctr12 <= (512)) begin //else if (ctr34 >(shift+256+dt) && ctr34 <= 512) begin  
selop = 0;  
selon = 1;  
end 
else begin  
selop = 0;  
selon = 0;  
end 
//----------- S 3 & 4 ------//  
if (ctr34 <=(del2-dt)) begin //if (ctr34 <=(shift-dt)) begin    
seloop = 1; 
seloon = 0; 
end 
else if (ctr34 >(del2-dt) && ctr34 <= (del2+dt)) begin //else if (ctr34 >(shift-dt) && ctr34 <= (shift+dt)) begin   
seloop = 0; 
seloon = 0; 
end 
else if (ctr34 >(del2+dt) && ctr34 <= (del2+256-dt)) begin //else if (ctr34 >(shift+dt) && ctr34 <= (shift+256-dt)) begin   
seloop = 0; 
seloon = 1; 
end 
else if (ctr34 >(del2+256-dt) && ctr34 <= (del2+256+dt)) begin  //else if (ctr34 >(shift+256-dt) && ctr34 <= (shift+256+dt)) begin  
seloop = 0; 
seloon = 0; 
end 
else if (ctr34 >(del2+256+dt) && ctr34 <= (512)) begin //else if (ctr34 >(shift+256+dt) && ctr34 <= 512) begin  
seloop = 1; 
seloon = 0; 
end 
else begin  
seloop = 0; 
seloon = 0; 
end 
//selo = clk;   
end 
...
...
...
...
next_ctr12 = ctr12+1;   
next_ctr34 = ctr34+1;   
endmodule
/////////////////////////
module clk_div2(clk,clk_div2);  
input clk;  
output clk_div2;    
reg clk_div2 = 1;   

reg [2:0]counter;   
reg [2:0]next_counter;  

always @ (posedge clk)  
begin   
counter = counter +1;   
if (counter>=2) begin   
clk_div2 <= ~clk_div2;  
counter = 0;    
end 
end 
endmodule  

My expectation was that if the "switch" toggles, del1 and del2 will get different values and the instruction set under "always @" will change accordingly. But its not working at all. I did some research on this and my guess is the regs dela1 and del2 are not resetting and hence it is in dont care condition. But I guess I dont know how to reset it, can you please help? What else might be the reason? I also tried setting del1 and del2 as wire, that approach doesnot work as well. Is something wrong with the way "always@" is set up?

\$\endgroup\$
  • 1
    \$\begingroup\$ Start with fixing your assignments, they are just the wrong way around: In the always @( * ) you should use blocking assignments =. In the @ (posedge clk_div2) you should use non blocking: <=. Then get a waveform display running and check what is happening. Oh and you should avoid using "derived clocks" (clk_div2). Use one general clock with an enable. \$\endgroup\$ – Oldfart Jul 31 at 18:37
  • \$\begingroup\$ Your code is kind of a mess. You are using non-blocking assignments for combinational logic, and mixing blocking and non-blocking assignments in a clocked block. Have you defined a clk_div2 module for U1? Why are you using the same identifier (clk_div2) for different purposes? \$\endgroup\$ – Elliot Alderson Jul 31 at 18:39
  • \$\begingroup\$ Please post a minimum verifiable example they demonstrates the issue. Please also properly indent and format the code \$\endgroup\$ – Tom Carpenter Jul 31 at 18:39
  • \$\begingroup\$ Sorry forgot the u1, added. I will fix the blocking and nonblocking issues tonight and try it out. Elliot, I see what you mean, that might be an error on my part, I will try to fix that too. But does that explain del1 and del2 being dont care? \$\endgroup\$ – Am1T Jul 31 at 18:46
  • \$\begingroup\$ del1 and del1 are defined as reg which is only 1-bit. Try defining them as reg [7:0]. \$\endgroup\$ – Greg Jul 31 at 19:00
0
\$\begingroup\$

del1 and del1 are defined as reg which is only 1-bit. Try defining them as reg [7:0].

Also fold in Oldfart's and Elliot's suggestion of fixing blocking (=) / non-blocking (<=) assignments. Combinational logic (eg: always @*) should use blocking (=). Sequentail logic (eg: always @(posesge clk)) should use non-blocking (<=)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.