PULPissimo FLL bypass
#1
Hello everyone,
Could someone please help me bypass the FLL logic ? I want to use an external clock for my design.
At the moment, I have removed the gf22_FLL instances and tried to connect soc_clk and per_clk directly to ref_clk.
Could anyone please share their experience of bypassing the FLL ? How did you handle the rest of the logic present in soc_clk_rst_gen.sv file ?
With this, I get error captured in the attachment. 

Cheers


Attached Files Thumbnail(s)
   
Reply
#2
Hello Supra,

ref_clock has a frequency of 32.769kHz, which is generated e.g. by a quartz oscillator on a real chip. I think you could use this signal directly, but then you whole design will be not faster than this.
The error you have posted, shows, that the JTAG process failed during the memory write/read test. My guess is, that you probably need to slow down the JTAG clock in the testbench, since it is way to fast for the memory of the design.
You can extend the period in the task "jtag_wait_halfperiod" of "jtag_pkg.sv".

If your design needs to run faster than of 32.769kHz, you could add and expose one or two more clock inputs at the top module and propagate them to the soc_clk_rst_gen. You can then generate the clock signals in the testbench, just like it has been done with the ref_clk.

I hope this will help you.

Kind regards.
Reply
#3
Hello heavySea,

Thank you very much for your reply. I currently see the following cases:

Case 1:  Original setup, no modifications to source code or tb
Works as expected. Hello world test passes. No problems.

Case 2:  FLL instantiations removed. No modifications to clocks
I removed the FLLs and instead used something like the following to propagate the clocks  in soc_clk_rst_gen.sv

Code:
            //SoC Clock
        assign s_clk_fll_soc = ref_clk_i;
           assign s_clk_soc = s_clk_fll_soc;
           assign soc_fll_slave_r_data_o = 'b0;
           assign soc_fll_slave_ack_o = 1'b1;
           assign soc_fll_slave_lock_o = 1'b1;

But this results in the problem mentioned at the top of this thread.
So, I tried changing "jtag_wait_halfperiod" from 50000 to 5000000 (x100 times slower !). With this modification, I do not see the reg access error (as shown in the original post).  But my simulation gets stuck at "Waiting for  end of computation". 

Case 3: FLL instantiations removed. Separate clocks for soc and jtag in test bench
I introduced a new net to distribute a faster clock to tmp_clk_ref when JTAG is not in action. This allows me to keep "jtag_wait_halfperiod" at the original 50000. This time too I get stuck at "Waiting for  end of computation". The change to soc_clk_rst_gen.sv is same as in case 2.

Have you faced this problem too? What logic is soc_clk_rst_gen.sv supposed to mimic if we do not use FLLs ?

Best Regards,
Supra
Reply
#4
Hello Supra,

Quote:I removed the FLLs and instead used something like the following to propagate the clocks  in soc_clk_rst_gen.sv

Code:
            //SoC Clock
        assign s_clk_fll_soc = ref_clk_i;
           assign s_clk_soc = s_clk_fll_soc;
           assign soc_fll_slave_r_data_o = 'b0;
           assign soc_fll_slave_ack_o = 1'b1;
           assign soc_fll_slave_lock_o = 1'b1;

You are on the right track. Technically you do not need the FLL Bus Interface, since you do not have the FLLs.
But you should make sure, that the clocks are not active during resets, e.g. by

Code:
assign s_clk_soc = ref_clk_i & rstn_glob_i;

Quote:But my simulation gets stuck at "Waiting for  end of computation".
Have you checked, if the core or any peripheral is still doing something? What program did you run? How does it print it's outputs? stdout or UART?


For case 3:

Quote:Separate clocks for soc and jtag in test bench
You don't need an additional clock for JTAG, since there is already one.
But you might want to have a separate clocks for SoC/CPU and peripherals (like there are two FLL's in the original design)

Code:
I introduced a new net to distribute a faster clock to tmp_clk_ref when JTAG is not in action.
It should not matter if JTAG is in action. Where does temp_clk_ref source from? What does it drive?


Quote:This time too I get stuck at "Waiting for  end of computation". The change to soc_clk_rst_gen.sv is same as in case 2.
Then have a look at the core where it gets stuck. The program counter would be a good start to look at.
Just out of curiosity, which core are you using? Ibex or Riscy?

Cheers
Reply
#5
Hi heavySea,

Thank you very much for your reply. 
Quote:But you should make sure, that the clocks are not active during resets, e.g. by

I did this but it did not really help. 

Quote:Have you checked, if the core or any peripheral is still doing something? What program did you run? How does it print it's outputs? stdout or UART?

I could not verify if something else was running at the time. I ran the "hello world" C program present in the rt-examples repo (https://github.com/pulp-platform/pulp-rt-examples). It prints using stdout.

Quote:But you might want to have a separate clocks for SoC/CPU and peripherals (like there are two FLL's in the original design)
I have done this. The code that I have divides the per_clock by 2 with respect to SoC using a simple clock divider logic.  So, two of the many outputs coming out of soc_clk_rst_gen`s instantiation are clk_soc_o (freq same as ref_clk_i) and clk_per_o (freq half of ref_clk_i).

Quote:It should not matter if JTAG is in action. Where does temp_clk_ref source from? What does it drive?
Sorry for being very unclear here. What I should have mentioned was that in tb_pulp.sv, we have the following section:
Code:
     if (ENABLE_EXTERNAL_DRIVER) begin
        tmp_rst_n      = s_rst_dpi_n;
        tmp_clk_ref    = design_s_clk_ref; //Use faster clock
        tmp_trstn      = w_bridge_trstn;
        tmp_tck        = w_bridge_tck;
        tmp_tdi        = w_bridge_tdi;
        tmp_tms        = w_bridge_tms;
        tmp_tdo        = w_tdo;
        tmp_bridge_tdo = w_tdo;

     end else if (ENABLE_OPENOCD) begin
        tmp_rst_n         = s_rst_n;
        tmp_clk_ref       = s_clk_ref; //uses JTAG freq clock
        tmp_trstn         = sim_jtag_trstn;
        tmp_tck           = sim_jtag_tck;
        tmp_tdi           = sim_jtag_tdi;
        tmp_tms           = sim_jtag_tms;
        tmp_tdo           = w_tdo;
        tmp_bridge_tdo    = w_tdo;
        sim_jtag_enable = 1'b1;

     end else begin
        tmp_rst_n      = s_rst_n;
        tmp_clk_ref    = design_s_clk_ref; //ises fast clock
        tmp_trstn      = s_trstn;
        tmp_tck        = s_tck;
        tmp_tdi        = s_tdi;
        tmp_tms        = s_tms;
        tmp_tdo        = w_tdo;
        tmp_bridge_tdo = w_tdo;

The s_clk_ref is generated using the following :
Code:
tb_clk_gen #( .CLK_PERIOD(REF_CLK_PERIOD) ) i_ref_clk_gen (.clk_o(s_clk_ref) );

where REF_CLK_PERIOD is 30517ns. Since this is too slow for my normal logic, I use 
Code:
parameter  DESIGN_REF_CLK_PERIOD = 5ns;
tb_clk_gen #( .CLK_PERIOD(DESIGN_REF_CLK_PERIOD) ) i_design_ref_clk_gen (.clk_o(design_s_clk_ref) );

I may have misunderstood this part of the test bench.  When I say JTAG is in action, I mean I allow  tmp_clk_ref to take the clk generated with REF_CLK_PERIOD when ENABLE_OPENOCD is true.

Quote:Then have a look at the core where it gets stuck. The program counter would be a good start to look at.

Just out of curiosity, which core are you using? Ibex or Riscy?

 I will have a look at the program counter now. Thank you very much for the pointer !
I am using Riscy. 

My ultimate goal is to tape out Pulpissimo. We do not have an FLL and I am stuck at this point of bypassing it. It would be awesome if you (or your team) could share the experience of working without an FLL. I am very thankful to you for guiding so far !

Cheers,
Supra
Reply
#6
Hi !

I was able to resolve this issue by modifying the pulp-sdk as discussed in https://github.com/pulp-platform/pulpiss...sues?q=fll .
Without changing pulp-rt/kernel/init.c, I simply could not get PULPissimo without fll modules to work at simulation level. 

The modifications to soc_clk_rst_gen.sv are simple. Just commented out the flls and connected output clocks to ref_clk and output resets to global reset. 


Cheers
Reply


Forum Jump: