-1

I have been struck at this point for quite some time now and would really help me out if someone can look into this and solve it. There are 4 inputs to a system - w, a,b,c. All are periodic inputs which are changing with time. The output is o. All are stored as signed 16 bit registers. When w is less than 16'b0000101100110011, the output (o) is directly equal to 'a'. When w is greater than this, the output changes to 'b' but this happens during the zero crossing of c, i.e. when it goes from positive to negative or vice-versa. So even if w is greater than the above specified value but c has not crossed its zero crossing, the output 'o' will continue to be 'a'. I am trying to see the value of MSB of 'c'. As soon it changes its value, I am trying to change the output from 'a' to 'b' but this is not happening as per the given code:

module trial(clk, w, a, b, c, o
    );

input clk;    
input signed [15:0] w;    
input signed [15:0] a;    
input signed [15:0] b;    
input signed [15:0] c;    
output signed [15:0] o;    
reg signed [15:0] temp;    
reg signed [15:0] temp1;    
reg signed [15:0] temp2;    


always @(posedge clk)    
 begin    
  if (w<16'b0000101100110011)    
   begin    
    temp = a;    
   end    
  else    
   begin    
    temp1 = 0;//Initializing the value of temp1    
    temp2 = 0;//Initializing the value of temp2      
    while (temp1 == temp2)    
     begin    
      temp1 = c[15];// storing the sign bit of input 'c'    
      repeat(1) @(posedge clock);// one clock cycle delay command (##1 was    not working)    
      temp2 = c[15];//storing the sign bit of input 'c' after one clock cycle    
     end    
    temp = b;    
   end    
  end    
 assign o = temp;    
endmodule  

The output changes from 'a' to 'b' instantly when 'w' becomes greater than 16'b0000101100110011. It does not wait fo the zero crossing of 'c'. Can some one point out if there is some mistake and probably a solution. Thanks

Shivang
  • 1
  • 2

2 Answers2

1

I think something like this will work too

module sample(clk, w, a, b, c, o );

input clk;    
input signed [15:0] w;    
input signed [15:0] a;    
input signed [15:0] b;    
input signed [15:0] c;    
output reg signed [15:0] o;    
reg signed [15:0] temp;    
reg signed [15:0] temp1;    
reg signed [15:0] temp2;    

reg signed [15:0] c_previous;
wire signed c_zero_cross;

assign c_zero_cross = (c_previous[15] == c[15]) ? 1'b0 : 1'b1;

always @(posedge clk) begin

    c_previous <= c;

    if (w < 16'b0000101100110011) begin    
         o <= a;          
    end    
    else begin    
        if(c_zero_cross) begin
            o <= b;
        end else begin
            o <= a;
        end
    end
end    

endmodule

o changes to 50 when c changes from 10 to -10

DBB
  • 467
  • 9
  • 23
  • Sorry but this code is not working. The output is always coming out to be ''a''. Even at the zero crossing of "c", the output did not change when w > 16'b0000101100110011. – Shivang Jan 29 '16 at 04:43
  • Its working fine for me. The only thing missing was making the variables signed and I converted zero crossing to one bit for clarity. – DBB Jan 30 '16 at 00:26
0

Dude, indent the code it will help you and us ;-)

If I understand your question and clock is the same clk signal, I suggest you something like this:

always @(posedge clk) begin    
    if (w<16'b0000101100110011) begin    
        temp <= a;    
        big  <= 0; //flag
    end    
    else begin    
        big <= 1; //flag
    end
end    

always @ (posedge c or negedge c) begin
    if (big == 1) begin
        temp <= b;
    end
end

Seems as you writing verilog logic as a C program logic. You should'n do it. You need to try to think how the hardware will build your wires. This is the parallelism power on your hands ;-)

Rule of thumb about = and <=. If you are in always @(posedge/negedge) block, use <=. But check http://www.asic-world.com/tidbits/blocking.html to better understand it.

  • 3
    You should use `<=` ( a non-blocking assignment) in clocked always blocks (`always@(posedge/negedge)`), but not in sequential blocks (`always@(*)`) – wilcroft Jan 28 '16 at 16:09
  • 1
    Your assigning `temp` in two always blocks; it will not synthesize. Plus `c` is a 16-bit value, so `posedge c or negedge c` doesn't make sense. – Greg Jan 28 '16 at 17:43
  • Greg, as on question he said "happens during the zero crossing of c" I assume this is a one bit input on this example code. – Roberto Alcantara Jan 28 '16 at 18:12
  • "c" is a 16 bit input only. But instead of using posedge c, we can use posedge c[15]. By using this also, I have not been able to get the correct output. Using this code, the transition is not happening from a to b when w >16'b0000101100110011. – Shivang Jan 29 '16 at 05:19
  • Can you post your testbench ? – Roberto Alcantara Jan 29 '16 at 11:16