0

I'm to trying to code a clock gating logic that allows data to pass only at the posedge write_clk_en. the code is compiled correctly in EDA playground but the output is not as intended.So according to code,

@ (posedge write_clk_en)begin data_in[3] <= 1'b1; end 

at this instance the write_clk_en is disabled, so data_in[3] NBA should be halted and it waits for next valid posedge (which is the next posedge of write_clk_en here), data_in[3] should be written. But that is not happening, rather the gated clock period is also getting considered and the NBA assignment is occurring even when write_clk_en is gated for 4th pulse.What could be the issue ?.the wave form is shown here.

enter image description here

the sv code :

module tb; logic [4:0] data_in; logic write_clk; logic write_clk_en; logic write_clk_mod; logic [5:0] write_clk_init; always//write_clk 500M begin write_clk =0; #10 write_clk = 1; #10 write_clk = 0; end initial begin $dumpfile("dump.vcd"); $dumpvars; #10000 $finish; end initial begin data_in=5'b00000; write_clk_init = 6'b000000; write_clk_mod=0; end initial begin write_clk_init =6'b110111; end initial begin repeat (3) begin @(posedge write_clk)begin if(write_clk_init[0]==1 || write_clk_init[0]==0) write_clk_mod<=write_clk_init[0]; end @(posedge write_clk)begin if(write_clk_init[1]==1 || write_clk_init[1]==0) write_clk_mod<=write_clk_init[1]; end @(posedge write_clk)begin if(write_clk_init[2]==1 || write_clk_init[2]==0) write_clk_mod<=write_clk_init[2]; end @(posedge write_clk)begin if(write_clk_init[3]==1 || write_clk_init[3]==0) write_clk_mod<=write_clk_init[3]; end @(posedge write_clk)begin if(write_clk_init[4]==1 || write_clk_init[4]==0) write_clk_mod<=write_clk_init[4]; end @(posedge write_clk)begin if(write_clk_init[5]==1 || write_clk_init[5]==0) write_clk_mod<=write_clk_init[5]; end end end always @ (*) begin write_clk_en = write_clk & write_clk_mod; end initial begin @ (posedge write_clk_en)begin data_in[0] <= 1'b1; end @ (posedge write_clk_en)begin data_in[1] <= 1'b1; end @ (posedge write_clk_en)begin data_in[2] <= 1'b1; end @ (posedge write_clk_en)begin data_in[3] <= 1'b1; end @ (posedge write_clk_en)begin data_in[4] <= 1'b1; end end endmodule 
1
  • 1
    looks like you got a glitch on wire_clk_en. Most likely due to the fact that you overused nbas in generating write_clk_mod. use blocking assignments there. Commented May 30, 2020 at 13:57

1 Answer 1

2

Within initial blocks, change your NBAs to BAs. NBAs should only be used within an always @(posedge clocksignal) block

Take also into account that in simulations, @(posedge clocksignal) blocks (without the reserved word always) are treated as delays (wait until a rising edge clk event happens, then continue simulation). By the way you have written these blocks in your initial statements, I didn't know for sure if you were aware of their true behaviour. I've rewritten those @(posedge) blocks to make the simulation flow a bit clear.

I have also merged some of your initial blocks into one. Every initial block you have is started at the same time (simulation time 0). Particulary, write_clk_init is assigned in two different initial blocks.

This edited code works as expected. It is also available at https://www.edaplayground.com/x/3VYk

OpenWavwe output

module tb; reg [4:0] data_in; reg write_clk; reg write_clk_en; reg write_clk_mod; reg [5:0] write_clk_init; initial begin $dumpfile("dump.vcd"); $dumpvars; #10000 $finish; end initial begin data_in = 5'b00000; write_clk_init = 6'b110111; write_clk_mod = 0; write_clk = 0; repeat (3) begin @(posedge write_clk); if(write_clk_init[0]==1 || write_clk_init[0]==0) write_clk_mod = write_clk_init[0]; @(posedge write_clk); if(write_clk_init[1]==1 || write_clk_init[1]==0) write_clk_mod = write_clk_init[1]; @(posedge write_clk); if(write_clk_init[2]==1 || write_clk_init[2]==0) write_clk_mod = write_clk_init[2]; @(posedge write_clk); if(write_clk_init[3]==1 || write_clk_init[3]==0) write_clk_mod = write_clk_init[3]; @(posedge write_clk); if(write_clk_init[4]==1 || write_clk_init[4]==0) write_clk_mod = write_clk_init[4]; @(posedge write_clk); if(write_clk_init[5]==1 || write_clk_init[5]==0) write_clk_mod = write_clk_init[5]; end end always @* begin write_clk_en = write_clk & write_clk_mod; end initial begin @(posedge write_clk_en); data_in[0] = 1'b1; @(posedge write_clk_en); data_in[1] = 1'b1; @(posedge write_clk_en); data_in[2] = 1'b1; @(posedge write_clk_en); data_in[3] = 1'b1; @(posedge write_clk_en); data_in[4] = 1'b1; end always begin write_clk = #10 ~write_clk; end endmodule 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.