Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to drive async clks during simulation #51

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

ginty
Copy link
Member

@ginty ginty commented Dec 31, 2020

This PR adds the ability to drive a free-running clk on a pin during simulation via this API:

pin(:my_pin).drive_clk(4.ns, 8.ns)  # On duration, Off duration

Here is a picture of an osc clk produced by this feature alongside a tck clock generated by the pattern timing:

image

This will be most useful when running an IP-level simulation where the IP has a clk input which would normally be supplied by the SoC (rather than the ATE). Until now such cases have had to be derived from the vector/pattern timing which makes it much harder to produce for the user.

Aside from scratching this itch, the primary motivation for this was to trial a hware/RTL-based (pin) wave driver rather than one which uses VPI callbacks (as used for all other waveforms currently produced by OrigenSim).
The VPI callback method is slower and is the main reason for OrigenSim performing slower in benchmarks vs other virtual tester tools.

For O2, the goal is to use this type of pin driver across the board and have Origen simply download the timing to each driver whenever the timeset is specified and then let the simulation freerun during wait events.

So here is the prototype driver -

module async_wave_driver(dout);
output reg dout;
// The duration of each edge. The values held here only apply if the
// corresponding enable is set, otherwise they are ignored
time t0 = 0;
time t1 = 0;
time t2 = 0;
time t3 = 0;
time t4 = 0;
time t5 = 0;
time t6 = 0;
time t7 = 0;
// Data value to be applied to the pin, typically corresponds to the
// "D" value during a drive cycle
reg drive_data = 0;
// Enables for each timing edge
reg [7:0] edge_enable = 0;
// Optional edge-specific data values
reg [7:0] edge_drive_data = 0;
// Selects the data source for the edge, 0 means apply 'drive_data' while a 1
// means apply the edge-specific value from 'edge_drive_data'
reg [7:0] drive_data_select = 0;
// Tell the driver to start. Once started it will run indefinitely until all
// edge enables are disabled (edge_enable == 0).
// It can be re-started by writing go=1 after enabling at least one edge.
reg go = 0;
always @(posedge go) begin
go = 0;
while (edge_enable != 0) begin
if (edge_enable[0]) begin
#(t0);
dout = drive_data_select[0] ? edge_drive_data[0] : drive_data;
end
if (edge_enable[1]) begin
#(t1);
dout = drive_data_select[1] ? edge_drive_data[1] : drive_data;
end
if (edge_enable[2]) begin
#(t2);
dout = drive_data_select[2] ? edge_drive_data[2] : drive_data;
end
if (edge_enable[3]) begin
#(t3);
dout = drive_data_select[3] ? edge_drive_data[3] : drive_data;
end
if (edge_enable[4]) begin
#(t4);
dout = drive_data_select[4] ? edge_drive_data[4] : drive_data;
end
if (edge_enable[5]) begin
#(t5);
dout = drive_data_select[5] ? edge_drive_data[5] : drive_data;
end
if (edge_enable[6]) begin
#(t6);
dout = drive_data_select[6] ? edge_drive_data[6] : drive_data;
end
if (edge_enable[7]) begin
#(t7);
dout = drive_data_select[7] ? edge_drive_data[7] : drive_data;
end
end
end
endmodule

It supports 8 timing edges per period, which I think is the same as the V93K and probably more than the Teradynes, though it could be easily increased if required.
Origen will set the timing for each driver by writing to the time t0-t7 variables and then updating the data and other configuration regs as required.

The final O2 driver will be more full-featured (e.g. supporting compare in addition to drive) and would also be synchronized to a global heartbeat representing the pattern cycle period rather than being free-running like this one (though it would still have an optional async mode like this one). i.e. the main loop would be @(posedge heartbeat) rather than while(1) like we have here.
It will also likely have some performance optimizations, e.g. such as doing no edge tracking in the common case of driving for a complete clk cycle.

I did a prototype of the heartbeat too, but I've commented it out for now since it would just be doing un-necessary simulation work in the O1 simulations:

//module timing(cycle_beat);
// output reg cycle_beat = 0;
//
// time cycle_period = 100;
// reg period_set = 0;
//
// initial begin
// forever begin
// if (period_set && cycle_period > 0) begin
// cycle_beat = 1;
// #($ceil(cycle_period / 2));
// cycle_beat = 0;
// #($ceil(cycle_period / 2));
// end else begin
// #(100);
// end
// end
// end
//endmodule

Finally I made the simulation timescale introspection a bit more robust, adding the ability to now interogate the timeunit and the precision. These are mainly intended for internal use by OrigenSim and are not documented in the user guides.

I plan to hard fork OrigenSim from this point into O2 soon and don't have any plans to further enhance O1 in this direction.

@redxeth be aware of this update as it's pretty useful for the IP-level simulations your team does.

Copy link
Member

@pderouen pderouen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

@mathieuperret01
Copy link

Hi All,
Just discovering that PR, which seems to be very handy, and I would really like to be able to use that.
Can it be merged ?
Thanks.

@ginty
Copy link
Member Author

ginty commented Jun 1, 2023

Hey @mathieuperret01, nice to hear from you, hope you're well.

Yeah this feature does look quite useful, I guess it just got forgotten about when I left.

@coreyeng, any objections to merging this?

@coreyeng
Copy link
Member

coreyeng commented Jun 1, 2023

This shouldn't break anything current, correct? I've been working on a branch anyway with my wreal stuff so I think its fine.

Copy link
Member

@priyavadan priyavadan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like a great update to me!

@mathieuperret01
Copy link

Hi All,
Can we merge that PR also ?
I think in combination with the other PR, we could have a gem tag update ?
Thanks.

@redxeth
Copy link
Member

redxeth commented Aug 23, 2023

@ginty would you be merging this or @priyavadan or who will do? @mathieuperret01 could do but he doesn't have Origen Core team priveleges? Should he have permissions perhaps?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants