0
\$\begingroup\$

I wrote somekind of prescaler in verilog to make sclk_adc signal from clk_i. by now my code looks like:

always @(posedge clk_i)
begin
//generation of sclk_adc
end

enter image description here

now i wonder is there any probability to load shift registers on pos/negedge of generated clock in always @(posedge clk_i) block?

When i wrote this outside the main always block

always @(negedge sclk_adc)
begin
    transdata = transtmp;
    dataInCh[ch_cnt][15:0] = transdata;
end 

always @(posedge sclk_adc)
begin
    dout = shiftOut [ch_cnt] [15];
    shiftOut [ch_cnt][15:0] = { shiftOut[ch_cnt] [14:0], 1'b0};
end 

It is simulated well in the GTKwave, but quartus started to complain about multiply reference to dout (my output), deservedly, i think. So it seems like i have to load them in main always block, but when i add those lines there, shift registers start to load with clk_i, not with the sclk_adc what is logical, but how to avoid this? Please, provide me any clue, thanks

\$\endgroup\$
3
  • \$\begingroup\$ You should share all the code you can. You haven't shared code that shows two references to dout, so it's hard for us to comment on how you can improve your code. \$\endgroup\$
    – The Photon
    Commented Jul 25, 2018 at 5:11
  • \$\begingroup\$ pastebin.com/NXUHLb3u \$\endgroup\$
    – dshee
    Commented Jul 25, 2018 at 6:32
  • \$\begingroup\$ now it is here (i am sorry it is my first verilog code. it is driver for adc circuit). But i faced another problem :c I almost get what i wanted link i needed dout loaded WITH posedge sclk_adc and transdata shift WITH negedge sclk. But they made it at another clk_i after event of pos/negedge, why? help me to explain this please \$\endgroup\$
    – dshee
    Commented Jul 25, 2018 at 6:41

2 Answers 2

0
\$\begingroup\$

From comments:

I almost get what i wanted link i needed dout loaded WITH posedge sclk_adc

You can just update dout on the edge of sclk_adc:

always @(posedge sclk_adc) 
    begin
    dout <= shiftOut [ch_cnt] [15];
    end

But if you do this, you can only update dout in this always block. You can use an asynchronous reset if you are concerned that your reset signal won't be asserted long enough to see an edge of the slow clock:

always @(posedge sclk_adc or posedge reset) begin
    if (reset) begin 
        dout <= 0;
    else begin
        dout <= shiftOut [ch_cnt] [15];
    end
end

You can't reset dout in the always block timed by clk_i if you're also going to set it in the block timed by sclk_adc.

Alternatively, since you are generating sclk_adc using a counter timed by clk_i, you could just arrange to assert sclk_adc one cycle earlier than you are doing now. It's quite common when generating slow clocks to actually generate several clocks at the same frequency, but delayed from each other by 1 or more cycles of the master clock, to allow timing different events on different phases of the slow clock.

\$\endgroup\$
1
  • \$\begingroup\$ According to you i will rewrite dout like this assign dout = shiftOut [15]; assign out_next = { shiftOut[14:0], 1'b0}; to not mention it in main block and will make another always with sclk_adc. but it still mystery why my pos and neg detectors did not work. Anyway, thank you a lot! \$\endgroup\$
    – dshee
    Commented Jul 26, 2018 at 4:00
0
\$\begingroup\$

Well i beat this one. I just needed to built rising and falling edge detector

all i neeg is that few lines

reg    main_reg;
wire    pos_sclk, neg_sclk; 
assign  pos_sclk = sclk_adc & ~main_reg;
assign  neg_sclk = ~sclk_adc & main_reg;

and in main clk block

main_reg <= sclk_adc;
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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