当前位置:网站首页>[quick start of Digital IC Verification] 19. Basic grammar of SystemVerilog learning 6 (thread internal communication... Including practical exercises)
[quick start of Digital IC Verification] 19. Basic grammar of SystemVerilog learning 6 (thread internal communication... Including practical exercises)
2022-07-07 15:26:00 【luoganttcc】
Reading guide : The author has the honor to be a pioneer in the field of electronic information in China “ University of electronic technology ” During postgraduate study , Touch the cutting edge Numbers IC Verification knowledge , I heard something like Huawei Hisilicon 、 Tsinghua purple light 、 MediaTek technology And other top IC related enterprises in the industry , Pairs of numbers IC Verify some knowledge accumulation and learning experience . Want to get started for help IC Verified friends , After one or two thoughts , This column is specially opened , In order to spend the shortest time , Take the least detours , Most learned IC Verify technical knowledge .
List of articles
- One 、 Description of content
- Two 、 Internal thread communication mechanism :Verilog event
- 3、 ... and 、 Internal thread communication mechanism :semaphore
- Four 、 Internal thread communication mechanism :mailbox
- 4.1、 mailbox mailbox
- 4.2、 Use new New Mailbox
- 4.3、 Verify the mailbox in the platform
- 4.4、 Verify the communication between asynchronous threads in the platform
- 4.5、 Verify the communication between synchronization threads in the platform
- 4.6、 Verify threads and internal communication in the platform
- x、 Practice
One 、 Description of content
- event event
- The control of time sequence between threads
- Flag language ( Semaphore )
- Management of shared areas between threads
- mailbox :mailbox
- Data transmission between threads uses
notes : The application scenarios of the three mechanisms are different , Can't replace each other .
Two 、 Internal thread communication mechanism :Verilog event
2.1、Verilog event
Verilog Used in language event Synchronization thread
Trigger Operator of event :
->
- It will not block the execution of the thread
wait for Event is triggered :
@
- Edge sensitive , total Thread execution is blocked
- Only when an event occurs change when , The thread will continue execution
When a thread is triggered before it is blocked , May cause competition The phenomenon
- Trigger is later than wait
2.2、SystemVerilog event
- Synchronization thread
- event Is a handle to a synchronization object , The Party group can be used as a parameter to pass to the subroutine
- There is no need to declare it as a global variable , It can be event Use as a shared resource
- The operator that triggers an event :
->
and->>
->>
Triggering requires The edge of a clock complete
- The operator waiting for an event to be triggered :
@
andwait()
@
Is waiting for an edge ;wait
Is waiting A state ;@
Waiting for an edge is easy to cause the situation that you can never wait for the trigger ,SV Improvements have been made. , Introducedtriggered
.
triggered
Function is used to check whether an event has been triggered , The return value is a statuswait(event_variable.triggered)
- If within the current simulation time range , event It has been triggered , Statements will not be blocked
- otherwise ,
wait(event.triggered)
The statement will wait until it is triggered - therefore , It is the safest and safest waiting statement
2.3、 event event : The statement blocks at the edge of the event
- Verilog Used in language event Synchronization thread , The event duration is the time point when the whole event is triggered .
- The operator that triggers the event :
->
( It will not block the execution of the thread ) - Wait for the event to be triggered :
@
( edge-triggered )
initial
In terms of software, it is parallel , But the actual operation time is also poor , So the first one initial Will execute first , the second initial After the meeting , But the difference between the two is very short !- so ,e1 At the first initial Is triggered first , In the second initial Wait for the trigger , obviously e1 I can't wait ;e2 At the first initial Wait first , In the second initial Is triggered again , therefore e2 Can be triggered .
2.4、 event event: Wait for an event to trigger
- event Edge sensitivity
- wait(event_variable.triggered) It is level sensitive
- There is no sequence with the trigger time
- There is no sequence with the trigger time
2.5、 The cycle of events
- When synchronizing events between two threads, you must pay attention to
- If used in a loop
wait(evnet.triggered)
, It must be ensured that before waiting for the next cycle Update simulation time - otherwise , The code will go into
0
Delayed cycle , Wait again and again when a single event triggers
- If used in a loop
- Be careful with zero delay cycles , Not recommended
wait(event_variable.triggered)
This usage , It doesn't block threads ; Suggest or use@ event_variable
, It blocks threads .
2.6、event Can be used as a parameter
- program The variables inside are static by default , added automatic Then it's not static .
this.done
It is the instantiated object in the class done
2.7、 Internal thread communication mechanism :event
Blocking event triggers ( Immediate effect )
- Use
->
The operator - Triggering an event will not block all processes currently waiting for the event
- The behavioral edge sensitive signal that triggers the event
- Use
Non blocking event triggers ( Wait until the non blocking trigger interval , Such as rising edge )
- Use
->>
The operator - Create a non blocking assignment at the time of the event
- In the non blocking area of simulation time ( Such as rising edge ) Update Events
- Use
Waiting for an event (SV & Verilog All have )
@event_name
@
The operator will prevent the process from executing , Until the event is blocked- Before the trigger process executes the trigger behavior , The waiting process must be executed
@
sentence , Triggering behavior does not prevent the process from waiting for events- If the triggering behavior occurs first , Then the waiting process will continue to wait
Persistent trigger :
triggered
(SV alone possess )- In the current simulation time interval , An event has been triggered , that triggered The event attribute is true , Otherwise it is false .
wait(event_name.triggered)
give an example :
notes :
event done_too = done;
: It is called the merging of events ( two-way ). operation done It's equivalent to operating done_too, In the same way done_too It is also equivalent to operation done;
- Event sequence :
wait_order()
- When a specified series of events occur in left to right order ,
wait_order
The process begins to execute - If the specified series of events are executed out of order ,
wait_order
The process will not execute
- When a specified series of events occur in left to right order ,
event a, b, c;
wait_order(a, b, c); // Must follow a->b->c The order of
- 1
- 2
- 3
- 4
- 5
- Event variables : Merge variables
- event Is a separate data type , You can assign values
- When assigning an event to another event , The original event and the destination event share the original event
- When assigning an event to another event , Two events are merged into one event
- Event variables
- When events merge , The assignment operation will only affect the execution of the destination event or the waiting operation
- When put event Assign a value to event1 when , If a thread is waiting event1, that The current waiting thread will be blocked , Unable to execute .
because
E2 = E1
Lead to T1 This thread is blocked for a long time and cannot be executed .terms of settlement : stay fork Assign values outside first , Wait again E2 Trigger , Here's the picture :
notes :while There is no time to update , So there's a problem , Running simulation will always block
- Cancel event
- When an event is assigned null when , The process synchronized with this time variable is invalid
- Compare events
- Different events can be compared
- be equal to
==
- It's not equal to
!=
- All equal to
===
( And equal to==
There is no difference ) - Not all equal to
!==
- If an event is null, Other event bits 1, The Boolean expression is 0
- be equal to
- Different events can be compared
3、 ... and 、 Internal thread communication mechanism :semaphore
3.1、 Flag language ( Semaphore ) semaphore
- Semaphore Usually used for Shared resources Allocation and synchronization of
- Shared resources in different processes are Mutually exclusive Use
- Create... In memory
semaphore
when , Similar to creating a basket (bucket
), The basket contains a certain number of keys (keys
) - Process before execution You must get a key from the basket
- When a particular process needs a key , Only A certain amount of All processes are running at the same time
- Semaphore yes SV Built in class , Provide the following Method (
function / task
)- establish semaphore:
new(keys_numbers)
- Obtain one or more keys :
get()
- Return one or more keys :
put()
- Non blocking Get one or more keys :
try_get()
- establish semaphore:
- In the verification platform , Often used
semaphore
Allocate shared resources , such as The system bus , At the same time , Only one driver can use the bus
Be careful : The above functions , If you don't write parameters , It has default parameters !
3.2、 Use new
function , establish semaphore buckets
- Be careful :
sem_a = new[4];
Just declare the array , Each semaphore has not specified the number of keys , So it's impossible toput
Of ! - Class creation (new) Entities use parentheses :
sem = new(2);
; Array creation (new) Entities use square brackets :sem_a = new[4];
3.3、 Semaphore acquisition and release and try_get
And get
paraphrase
try_get
Return if you can't get it 0;get
Wait until you can't get it
Four 、 Internal thread communication mechanism :mailbox
4.1、 mailbox mailbox
- Mailbox yes SV Communication mode between different processes , adopt mailbox Information can be passed between different processes
- Data in a process , adopt mailbox Pass it on to another process ; When mailbox When there is no data in , The thread will wait
- mailbox Similar to a FIFO, You can set a certain depth queue size
- When the amount of information in the mailbox reaches the depth of the mailbox , Mailbox is full
- If the mailbox is full , The process can no longer store information in the mailbox , Until the information in the mailbox is taken , The mailbox is no longer full
- Email is SV Built in class , Provide the following methods
- New Mailbox :
new()
- Put the information into the mailbox :
put()
- Try to put the information into the mailbox without blocking :
try_put()
- Get the information from the mailbox :
get()
orpeek()
- Non blocking retrieval of information from the mailbox :
try_get()
ortry_peek()
- New Mailbox :
4.2、 Use new New Mailbox
4.3、 Verify the mailbox in the platform
- How to pass information between two threads ?
- generator (
generator
) Generate transaction packets , Then pass it to the drive (driver
)driver
Pass packets toDUT
,driver
Also do some follow sequential Related work !
- Generators and drives must be Asynchronous operations ( Mailbox is asynchronous FIFO)
- Synchronous operation also requires handshake , There is no constraint relationship between sending and fetching asynchronous operations
- generator (
program mailbox_example(bus_if.TB bus, ...);
class Generator
Transaction tr; // Classes are nested inside ,tr Is handle
mailbox mbx; //***** Define mailbox
function new(mailbox mbx); // This new yes generator Do initialization new function , When initializing the function outside, you will create a mailbox , That is to say new The mailbox will be created when , then mbx Pass to this.mbx. Note that the parameters inside are formal parameters , With the above mbx It can be different
this.mbx = mbx;
endfunction
task run; // The function is to generate random excitation , Then put the random incentives into the mailbox ,class Driver I will go in the afternoon get This incentive
repeat(10) begin
tr = new;
assert(tr.randomize); // Randomize all variables
mbx.put(tr); //***** tr Put it in the mailbox
end
entask
endclass
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
class Driver
Transaction tr;
mailbox mbx; //***** Define mailbox
function new(mailbox mbx);
this.mbx = mbx;
endfunction
task run;
repeat(10) begin
mbx.get(tr); //***** Get tr
@(posedge busif.cb.ack)
... // Actual physical timing
end
endtask
endclass
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
These two classes are just defined Generator and Driver, Equivalent to drawing , To use , We also need the code to talk about its instantiation , The code is as follows :
mailbox mbx; //***** In the same mbx It transmits data
Generator gen;
Driver drv;
initial begin
mbx = new; //***** Create a mailbox with infinite depth
gen = new(mbx); //***** Create two objects , That's instantiation , When creating objects, put mbx Pass it on
drv = new(mbx); //*****
end
fork
gen.run(); // Generate random excitation
drv.run();
join
endprogram
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- Generator The generated message is usually defined as Transaction
Summary : such as generator Want to driver send data , First of all, it will be in gen Create a mailbox inside , then put Put in the data , And then driver Create a mailbox inside , adopt get To get data . Last but not least env Instantiate inside , Connect the two mailboxes .
4.4、 Verify the communication between asynchronous threads in the platform
- If synchronization is required between the generator and the drive , You need to add additional handshake information
4.5、 Verify the communication between synchronization threads in the platform
- If synchronization is required between the generator and the drive , You need to add additional handshake messages
4.6、 Verify threads and internal communication in the platform
- A lot of components , The communication between components is through mailbox
Environmental Science ENV, First time to understand the use of email
- Don't pay too much attention to the following , Not actually complete code , It doesn't make much sense , Just know the mailbox section !
x、 Practice
X.1、event practice
x.1.1、 Thread waiting @
And trigger ->
demo
thread_communication.sv
module thread_com();
event e1, e2;
initial begin
fork
begin
$display("******@%0d, event1 before trigger", $time);
->e1;
@e2;
$display("******@%0d, event1 after trigger", $time);
end
begin
$display("******@%0d, event2 before trigger", $time);
->e2;
@e1;
$display("******@%0d, event2 after trigger", $time);
end
join
end
endmodule
******@0, event1 before trigger
******@0, event2 before trigger
******@0, event1 after trigger
- The concurrent behavior of concurrent threads is the behavior of simulation tools , At the same time at zero , But in fact, when the instruction is executed , Or execute the above thread first , There is a slight
δ
Time difference - In the above code
e1
Because it is triggered first and then wait , So you can't wait !
x.1.2、 Thread waiting wait(event_name.triggered)
And trigger ->
demo
thread_communication.sv
module thread_com(); event e1, e2; initial begin fork begin $display("******@%0d, event1 before trigger", $time); ->e1; //@e2; wait(e2.triggered) $display("******@%0d, event1 after trigger", $time); end begin $display("******@%0d, event2 before trigger", $time); ->e2; //@e1; wait(e2.triggered) $display("******@%0d, event2 after trigger", $time); end join end endmodule
******@0, event1 before trigger ******@0, event2 before trigger ******@0, event2 after trigger ******@0, event1 after trigger
wait(event_name.triggered)
wait for , As long as it has been triggered before !
x.1.3、event
Pass as a parameter demo
thread_communication.sv
class trigger_gen; event done; function new(input event ext_done); this.done = ext_done; endfunction task run(); #10; $display("******@%0d:trigger done by -> done", $time); ->done; endtask endclass //Parameter event event ext_done; trigger_gen trg_gen; initial begin #5; fork begin trg_gen = new(ext_done); trg_gen.run; end begin $display("******@%0d:wait for ext_done trg_gen", $time); @(ext_done); $display("******@%0d:after ext_done trigger_gen by gen.run", $time); end join end
******@5:wait for ext_done trg_gen ******@15:trigger done by -> done ******@15:after ext_done trigger_gen by gen.run
- meanwhile , Here, also pay attention to two-way assignment ( Merger of events )
X.2、semaphore practice
thread_communication.sv
//Semaphore semaphore sem[]; task send(input int sem_num, thread_num); sem[sem_num].get(1); $display("******@%0d:thread(%0d) get the key", $time, thread_num); sem[sem_num].put(1); endtask initial begin #50; sem = new[4]; foreach(sem[i]) sem[i] = new(1); repeat(3) begin fork send(0, 0); send(0, 1); join #1; end end
rslt.log
******@50:thread(0) get the key ******@50:thread(1) get the key ******@51:thread(0) get the key ******@51:thread(1) get the key ******@52:thread(0) get the key ******@52:thread(1) get the key
- If the addition delay , But you can't put it directly
send
Medium , belongfork...join
outside
X.3、mailbox practice
X.3.1、 Basic integer passing ( Mailbox asynchrony )Demo
thread_communication.sv
mailbox mb; int mb_in; int mb_out; initial begin #80; mb = new(20); fork for(int i; i<8; i++) begin #1; mb_in = 2*i+1; $display("******@%0d, mb in(%0d) : %0d", $time, i, mb_in); mb.put(mb_in); end for(int i; i<8; i++) begin #2; mb.get(mb_out); $display("******@%0d, mb out(%0d) : %0d", $time, i, mb_out); end join end
rslt.log
******@81, mb in(0) : 1 ******@82, mb out(0) : 1 ******@82, mb in(1) : 3 ******@83, mb in(2) : 5 ******@84, mb out(1) : 3 ******@84, mb in(3) : 7 ******@85, mb in(4) : 9 ******@86, mb out(2) : 5 ******@86, mb in(5) : 11 ******@87, mb in(6) : 13 ******@88, mb out(3) : 7 ******@88, mb in(7) : 15 ******@90, mb out(4) : 9 ******@92, mb out(5) : 11 ******@94, mb out(6) : 13 ******@96, mb out(7) : 15
X.3.2、 Basic integer passing ( Mailbox synchronization )Demo
thread_communication.sv
mailbox mb; int mb_in; int mb_out; event mb_e; initial begin #80; mb = new(20); fork for(int i; i<8; i++) begin #1; mb_in = 2*i+1; $display("******@%0d, mb in(%0d) : %0d", $time, i, mb_in); mb.put(mb_in); @mb_e; end for(int i; i<8; i++) begin #2; mb.get(mb_out); $display("******@%0d, mb out(%0d) : %0d", $time, i, mb_out); ->mb_e; end join end
******@81, mb in(0) : 1 ******@82, mb out(0) : 1 ******@83, mb in(1) : 3 ******@84, mb out(1) : 3 ******@85, mb in(2) : 5 ******@86, mb out(2) : 5 ******@87, mb in(3) : 7 ******@88, mb out(3) : 7 ******@89, mb in(4) : 9 ******@90, mb out(4) : 9 ******@91, mb in(5) : 11 ******@92, mb out(5) : 11 ******@93, mb in(6) : 13 ******@94, mb out(6) : 13 ******@95, mb in(7) : 15 ******@96, mb out(7) : 15
X.3.3、 Pass on class data
thread_communication.sv
class transaction; rand bit [15:0] addr; rand bit [31:0] data; constraint c1{ addr inside { [0:100], [1000:2000]}; data inside { 32'h5a5a_5a5a, 32'ha5a5a5, 32'hFFFF_FFFF}; } endclass class generator; transaction tr; mailbox mbx; int i=0; function new(input mailbox mb); this.mbx = mb; endfunction task run(); repeat(10) begin tr = new(); tr.randomize(); $display("******@%0d:generator %0d th (addr=%h, data=%h)", $time, i, tr.addr, tr.data); mbx.put(tr); i++; end endtask endclass class driver; transaction tr; mailbox mbx; int i=0; function new(input mailbox mb); this.mbx = mb; endfunction task run(); repeat(10) begin mbx.get(tr); $display("******@%0d:driver %0d th (addr=%h, data=%h)", $time, i, tr.addr, tr.data); i++; end endtask endclass mailbox mb1 = new(20); generator gen = new(mb1); driver drv = new(mb1); initial begin #100; fork gen.run(); drv.run(); join end
rslt.log
******@100:generator 0 th (addr=047f, data=ffffffff) ******@100:generator 1 th (addr=04b9, data=5a5a5a5a) ******@100:generator 2 th (addr=06e0, data=00a5a5a5) ******@100:generator 3 th (addr=0489, data=5a5a5a5a) ******@100:generator 4 th (addr=005e, data=5a5a5a5a) ******@100:generator 5 th (addr=0567, data=5a5a5a5a) ******@100:generator 6 th (addr=05ca, data=ffffffff) ******@100:generator 7 th (addr=040d, data=ffffffff) ******@100:generator 8 th (addr=0490, data=ffffffff) ******@100:generator 9 th (addr=05fe, data=00a5a5a5) ******@100:driver 0 th (addr=047f, data=ffffffff) ******@100:driver 1 th (addr=04b9, data=5a5a5a5a) ******@100:driver 2 th (addr=06e0, data=00a5a5a5) ******@100:driver 3 th (addr=0489, data=5a5a5a5a) ******@100:driver 4 th (addr=005e, data=5a5a5a5a) ******@100:driver 5 th (addr=0567, data=5a5a5a5a) ******@100:driver 6 th (addr=05ca, data=ffffffff) ******@100:driver 7 th (addr=040d, data=ffffffff) ******@100:driver 8 th (addr=0490, data=ffffffff) ******@100:driver 9 th (addr=05fe, data=00a5a5a5)
32'ha5a5a5
namely32'h00a5_a5a5
class driver
Mediumtr
did notnew
, Here we will have another in-depth understandingnew
The effect of ;tr = new;
The way of is actually an address randomly generated by the system ( Memory space entity ) Given totr
, Although not used herenew
But we used mailboxget
It means getting the address from the outside ( Memory space entity )!
边栏推荐
- TypeScript 发布 4.8 beta 版本
- Pit avoidance: description of null values in in and not in SQL
- [follow Jiangke University STM32] stm32f103c8t6_ PWM controlled DC motor_ code
- [server data recovery] data recovery case of raid failure of a Dell server
- What are PV and UV? pv、uv
- 8大模块、40个思维模型,打破思维桎梏,满足你工作不同阶段、场景的思维需求,赶紧收藏慢慢学
- Novel Slot Detection: A Benchmark for Discovering Unknown Slot Types in the Dialogue System
- What is data leakage
- There is a cow, which gives birth to a heifer at the beginning of each year. Each heifer has a heifer at the beginning of each year since the fourth year. Please program how many cows are there in the
- CTFshow,信息搜集:web7
猜你喜欢
Unity之ASE实现卡通火焰
#HPDC智能基座人才发展峰会随笔
CTFshow,信息搜集:web8
Niuke real problem programming - Day11
CTFshow,信息搜集:web3
asp. Netnba information management system VS development SQLSERVER database web structure c programming computer web page source code project detailed design
Ctfshow, information collection: web12
银行需要搭建智能客服模块的中台能力,驱动全场景智能客服务升级
Ctfshow, information collection: Web3
CTFshow,信息搜集:web14
随机推荐
What are the safest securities trading apps
Pit avoidance: description of null values in in and not in SQL
Novel Slot Detection: A Benchmark for Discovering Unknown Slot Types in the Dialogue System
使用Scrapy框架爬取网页并保存到Mysql的实现
【数字IC验证快速入门】25、SystemVerilog项目实践之AHB-SRAMC(5)(AHB 重点回顾,要点提炼)
MongoD管理数据库的方法介绍
CTFshow,信息搜集:web8
Typescript release 4.8 beta
TypeScript 发布 4.8 beta 版本
Unity's ASE realizes cartoon flame
“百度杯”CTF比赛 2017 二月场,Web:include
写一篇万字长文《CAS自旋锁》送杰伦的新专辑登顶热榜
8大模块、40个思维模型,打破思维桎梏,满足你工作不同阶段、场景的思维需求,赶紧收藏慢慢学
【数字IC验证快速入门】24、SystemVerilog项目实践之AHB-SRAMC(4)(AHB继续深入)
【兰州大学】考研初试复试资料分享
[quick start of Digital IC Verification] 29. Ahb-sramc (9) (ahb-sramc svtb overview) of SystemVerilog project practice
2022年5月互联网医疗领域月度观察
leetcode 241. Different Ways to Add Parentheses 为运算表达式设计优先级(中等)
Ctfshow, information collection: web6
A need to review all the knowledge, H5 form is blocked by the keyboard, event agent, event delegation