Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
This commit is contained in:
parent
00c9e58006
commit
eb258d7df7
|
|
@ -102,6 +102,9 @@ package std;
|
|||
// IEEE 1800-specified standard "semaphore"
|
||||
class semaphore;
|
||||
protected int m_keyCount;
|
||||
protected int m_nextKeyCount = '1;
|
||||
protected longint unsigned m_ticket = 0;
|
||||
protected longint unsigned m_nextTicket = 0;
|
||||
|
||||
function new(int keyCount = 0);
|
||||
m_keyCount = keyCount;
|
||||
|
|
@ -113,19 +116,26 @@ package std;
|
|||
|
||||
task get(int keyCount = 1);
|
||||
`ifdef VERILATOR_TIMING
|
||||
while (m_keyCount < keyCount) begin
|
||||
wait (m_keyCount >= keyCount);
|
||||
longint unsigned ticket;
|
||||
// Fast path: take if keys fit AND either no one is queued, or
|
||||
// the head still doesn't fit (so we're not stealing its keys).
|
||||
if (m_keyCount >= keyCount && m_nextKeyCount > m_keyCount) begin
|
||||
m_keyCount -= keyCount;
|
||||
return;
|
||||
end
|
||||
ticket = m_nextTicket++;
|
||||
wait (m_ticket == ticket);
|
||||
m_nextKeyCount = keyCount;
|
||||
wait (m_keyCount >= keyCount);
|
||||
m_keyCount -= keyCount;
|
||||
m_ticket++;
|
||||
`endif
|
||||
endtask
|
||||
|
||||
function int try_get(int keyCount = 1);
|
||||
if (m_keyCount >= keyCount) begin
|
||||
m_keyCount -= keyCount;
|
||||
return 1;
|
||||
end
|
||||
return 0;
|
||||
if (m_keyCount < keyCount) return 0;
|
||||
m_keyCount -= keyCount;
|
||||
return 1;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
|
|
|
|||
|
|
@ -1162,6 +1162,17 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
|
|||
}
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
}
|
||||
void visit(AstWait* nodep) override {
|
||||
puts("wait(");
|
||||
iterateConst(nodep->condp());
|
||||
puts(")");
|
||||
if (nodep->stmtsp()) {
|
||||
puts(" ");
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
} else {
|
||||
puts(";\n");
|
||||
}
|
||||
}
|
||||
void visit(AstCAwait* nodep) override {
|
||||
AstCMethodHard* methodp = VN_CAST(nodep->exprp(), CMethodHard);
|
||||
UASSERT_OBJ(methodp, nodep, "AstCAwait expression must be an AstCMethodHard");
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ module Vt_debug_emitv_t;
|
|||
end
|
||||
#1;
|
||||
$write("After #1 delay");
|
||||
wait((clk == 'sh1)) $write("After wait(clk == 1)");
|
||||
end
|
||||
end
|
||||
bit [6:5] [4:3] [2:1] arraymanyd[10:11][12:13][14:15];
|
||||
|
|
@ -757,6 +758,12 @@ endmodule
|
|||
package Vt_debug_emitv_std;
|
||||
class Vt_debug_emitv_semaphore;
|
||||
int signed m_keyCount;
|
||||
int signed m_nextKeyCount;
|
||||
m_nextKeyCount = 32'hffffffff;
|
||||
longint m_ticket;
|
||||
m_ticket = 64'h0;
|
||||
longint m_nextTicket;
|
||||
m_nextTicket = 64'h0;
|
||||
function new;
|
||||
input int signed keyCount;
|
||||
m_keyCount = keyCount;
|
||||
|
|
@ -766,29 +773,41 @@ package Vt_debug_emitv_std;
|
|||
m_keyCount = (m_keyCount + keyCount);
|
||||
endtask
|
||||
task get;
|
||||
longint __Vincrement1;
|
||||
input int signed keyCount;
|
||||
while ((m_keyCount < keyCount)) begin
|
||||
begin
|
||||
|
||||
???? // WAIT
|
||||
(m_keyCount >= keyCount)end
|
||||
end
|
||||
m_keyCount = (m_keyCount - keyCount);
|
||||
endtask
|
||||
function try_get;
|
||||
input int signed keyCount;
|
||||
longint ticket;
|
||||
begin : label3
|
||||
try_get = /*CRESET*/;
|
||||
if ((m_keyCount >= keyCount)) begin
|
||||
ticket = /*CRESET*/;
|
||||
if (((m_keyCount >= keyCount) && (m_nextKeyCount
|
||||
>
|
||||
m_keyCount))) begin
|
||||
begin
|
||||
m_keyCount = (m_keyCount -
|
||||
keyCount);
|
||||
try_get = 'sh1;
|
||||
disable label3;
|
||||
end
|
||||
end
|
||||
try_get = 'sh0;
|
||||
disable label3;
|
||||
__Vincrement1 = m_nextTicket;
|
||||
m_nextTicket = (m_nextTicket + 64'h1);
|
||||
ticket = __Vincrement1;
|
||||
wait((m_ticket == ticket));
|
||||
m_nextKeyCount = keyCount;
|
||||
wait((m_keyCount >= keyCount));
|
||||
m_keyCount = (m_keyCount - keyCount);
|
||||
m_ticket = (m_ticket + 64'h1);
|
||||
end
|
||||
endtask
|
||||
function try_get;
|
||||
input int signed keyCount;
|
||||
begin : label4
|
||||
try_get = /*CRESET*/;
|
||||
if ((m_keyCount < keyCount)) begin
|
||||
try_get = 'sh0;
|
||||
disable label4;
|
||||
end
|
||||
m_keyCount = (m_keyCount - keyCount);
|
||||
try_get = 'sh1;
|
||||
disable label4;
|
||||
end
|
||||
endfunction
|
||||
endclass
|
||||
|
|
@ -807,12 +826,12 @@ package Vt_debug_emitv_std;
|
|||
p
|
||||
???? // CLASSREFDTYPE 'process'
|
||||
;
|
||||
begin : label4
|
||||
begin : label5
|
||||
self = /*CRESET*/;
|
||||
p = new();
|
||||
$c(p.m_process = vlProcess;);
|
||||
self = p;
|
||||
disable label4;
|
||||
disable label5;
|
||||
end
|
||||
endfunction
|
||||
task set_status;
|
||||
|
|
@ -820,10 +839,10 @@ package Vt_debug_emitv_std;
|
|||
$c(m_process->state(s););
|
||||
endtask
|
||||
function status;
|
||||
begin : label5
|
||||
begin : label6
|
||||
status = /*CRESET*/;
|
||||
status = ($c(m_process->state()));
|
||||
disable label5;
|
||||
disable label6;
|
||||
end
|
||||
endfunction
|
||||
task kill;
|
||||
|
|
@ -837,12 +856,9 @@ package Vt_debug_emitv_std;
|
|||
set_status(process::RUNNING);
|
||||
endtask
|
||||
task await;
|
||||
|
||||
???? // WAIT
|
||||
((status() == process::FINISHED) || (status()
|
||||
==
|
||||
process::
|
||||
KILLED))endtask
|
||||
wait(((status() == process::FINISHED) ||
|
||||
(status() == process::KILLED)));
|
||||
endtask
|
||||
task killQueue;
|
||||
ref
|
||||
???? // CLASSREFDTYPE 'process'
|
||||
|
|
@ -898,12 +914,12 @@ package Vt_debug_emitv_std;
|
|||
???? // SYSTEMCSECTION
|
||||
function get_randstate;
|
||||
string s;
|
||||
begin : label6
|
||||
begin : label7
|
||||
get_randstate = /*CRESET*/;
|
||||
s = string'($c(0));
|
||||
$c(s = m_process->randstate(););
|
||||
get_randstate = s;
|
||||
disable label6;
|
||||
disable label7;
|
||||
end
|
||||
endfunction
|
||||
task set_randstate;
|
||||
|
|
@ -989,11 +1005,11 @@ package Vt_debug_emitv___024unit;
|
|||
???? // CLASSREFDTYPE 'Cls'
|
||||
;
|
||||
input int signed member;
|
||||
begin : label7
|
||||
begin : label8
|
||||
rand_restricted = randomize() with (
|
||||
???? // CONSTRAINTEXPR
|
||||
(item.rmember1 < member)) ;
|
||||
disable label7;
|
||||
disable label8;
|
||||
end
|
||||
endfunction
|
||||
endpackage
|
||||
|
|
@ -1014,13 +1030,13 @@ module Vt_debug_emitv_sub;
|
|||
endtask
|
||||
function f;
|
||||
input int signed v;
|
||||
begin : label8
|
||||
begin : label9
|
||||
if ((v == 'sh0)) begin
|
||||
f = 'sh21;
|
||||
disable label8;
|
||||
disable label9;
|
||||
end
|
||||
f = ({32'h1{{31'h0, v[2]}}} + 32'h1);
|
||||
disable label8;
|
||||
disable label9;
|
||||
end
|
||||
endfunction
|
||||
real r;
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ module t (/*AUTOARG*/
|
|||
if (|downto_32[60-:7]) $write("");
|
||||
if (the_ifaces[2].ifsig) $write("");
|
||||
#1 $write("After #1 delay");
|
||||
wait(clk == 1) $write("After wait(clk == 1)");
|
||||
end
|
||||
|
||||
bit [6:5][4:3][2:1] arraymanyd[10:11][12:13][14:15];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
[0] DRV locked
|
||||
[5] DRV unlocked
|
||||
[5] MON locked
|
||||
[5] MON unlocked
|
||||
[5] DRV locked
|
||||
[10] DRV unlocked
|
||||
[10] MON locked
|
||||
[10] MON unlocked
|
||||
[10] DRV locked
|
||||
[15] DRV unlocked
|
||||
[15] MON locked
|
||||
[15] MON unlocked
|
||||
*-* All Finished *-*
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of either the GNU Lesser General Public License Version 3
|
||||
# or the Perl Artistic License Version 2.0.
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute(expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`timescale 1ns / 1ns
|
||||
module t;
|
||||
semaphore sem = new(1);
|
||||
integer i;
|
||||
|
||||
task driver;
|
||||
repeat (3) begin
|
||||
sem.get(1);
|
||||
$display("[%0t] DRV locked", $time);
|
||||
#5 sem.put(1);
|
||||
$display("[%0t] DRV unlocked", $time);
|
||||
end
|
||||
endtask
|
||||
|
||||
task monitor;
|
||||
for (i = 0; i < 3; i = i + 1) begin
|
||||
#1 sem.get(1);
|
||||
$display("[%0t] MON locked", $time);
|
||||
sem.put(1);
|
||||
$display("[%0t] MON unlocked", $time);
|
||||
end
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
fork
|
||||
driver();
|
||||
monitor();
|
||||
join
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
[3] C got 1
|
||||
[3] C put 1
|
||||
[4] D put 2
|
||||
[4] A got 4
|
||||
[5] A put 3
|
||||
[5] B got 3
|
||||
*-* All Finished *-*
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of either the GNU Lesser General Public License Version 3
|
||||
# or the Perl Artistic License Version 2.0.
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute(expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 Antmicro
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`timescale 1ns / 1ns
|
||||
module t;
|
||||
semaphore sem = new(2);
|
||||
|
||||
initial begin
|
||||
fork
|
||||
begin
|
||||
#1 sem.get(4);
|
||||
$write("[%0t] A got 4\n", $time);
|
||||
#1
|
||||
sem.put(3);
|
||||
$write("[%0t] A put 3\n", $time);
|
||||
end
|
||||
begin
|
||||
#2 sem.get(3);
|
||||
$write("[%0t] B got 3\n", $time);
|
||||
end
|
||||
begin
|
||||
#3 sem.get(1);
|
||||
$write("[%0t] C got 1\n", $time);
|
||||
sem.put(1);
|
||||
$write("[%0t] C put 1\n", $time);
|
||||
end
|
||||
begin
|
||||
#4 sem.put(2);
|
||||
$write("[%0t] D put 2\n", $time);
|
||||
end
|
||||
join
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue