Skip to content

Commit 947bbfc

Browse files
committed
0.0.2
- (#25) - Correct issue passing string-type parameters Signed-off-by: Matthew Ballance <[email protected]>
1 parent 6e6c98c commit 947bbfc

File tree

7 files changed

+284
-3
lines changed

7 files changed

+284
-3
lines changed

doc/ChangeLog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
## 0.0.2
3+
- (#25) - Correct issue passing string-type parameters
4+
5+

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import sysconfig
77
from setuptools import Extension, setup, find_namespace_packages
88

9-
version="0.0.1"
9+
version="0.0.2"
1010

1111
proj_dir = os.path.dirname(os.path.abspath(__file__))
1212
pythondir = os.path.join(proj_dir, "src")

src/hdl_if/impl/call/gen_sv_class.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ def py2sv_func(self, type):
512512
ctypes.c_uint16 : "PyLong_AsLong",
513513
ctypes.c_uint32 : "PyLong_AsLong",
514514
ctypes.c_uint64 : "PyLong_AsUnsignedLongLong",
515-
str : "string",
515+
str : "PyUnicode_AsUTF8",
516516
ctypes.py_object : ""
517517
}
518518
if type not in type_m.keys():
@@ -534,7 +534,7 @@ def sv2py_func(self, type, var):
534534
ctypes.c_uint16 : "PyLong_FromLong",
535535
ctypes.c_uint32 : "PyLong_FromLong",
536536
ctypes.c_uint64 : "PyLong_FromUnsignedLongLong",
537-
str : "string"
537+
str : "PyUnicode_FromString"
538538
}
539539
if type in type_m.keys():
540540
return "pyhdl_if::%s(%s)" % (type_m[type], var)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
import ctypes as ct
3+
import hdl_if as hif
4+
5+
@hif.api
6+
class WishboneInitiator(object):
7+
8+
@hif.imp
9+
async def is_eq_hello(self, val : str) -> ct.c_bool:
10+
pass
11+
12+
@hif.imp
13+
async def write(self, addr : ct.c_uint32, data : ct.c_uint32):
14+
pass
15+
16+
@hif.imp
17+
async def read(self, addr : ct.c_uint32) -> ct.c_uint32:
18+
pass
19+
20+
@hif.api
21+
class Test(object):
22+
23+
@hif.exp
24+
async def run(self, bfm : ct.py_object):
25+
errors = 0
26+
print("run")
27+
28+
for i in range(64):
29+
wr_val = (i+1)
30+
print(f'[Py] writing: {wr_val}')
31+
await bfm.write(0x8000_0000+(4*i), wr_val)
32+
rd = await bfm.read(0x8000_0000+(4*i))
33+
print(f'[Py] readback: {rd}')
34+
if wr_val != rd:
35+
errors += 1
36+
37+
is_eq_1 = await bfm.is_eq_hello("hello")
38+
is_eq_2 = await bfm.is_eq_hello("goodbye")
39+
print("is_eq_1: %s" % is_eq_1, flush=True)
40+
print("is_eq_2: %s" % is_eq_2, flush=True)
41+
42+
if not is_eq_1:
43+
errors += 1
44+
45+
if is_eq_2:
46+
errors += 1
47+
48+
with open("status.txt", "w") as fp:
49+
fp.write("%s: %d errors\n" % (("PASS" if errors==0 else "FAIL"), errors))
50+
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
2+
module call_sv_bfm;
3+
import pyhdl_if::*;
4+
import call_sv_bfm_pkg::*;
5+
6+
reg clk = 0;
7+
reg reset = 1;
8+
initial begin
9+
10+
clk = 0;
11+
forever begin
12+
#10ns;
13+
clk = ~clk;
14+
end
15+
end
16+
17+
wire[31:0] dat_r, dat_w;
18+
wire[31:0] adr;
19+
wire stb, cyc, we;
20+
reg ack_r;
21+
wire ack = (ack_r && cyc && stb);
22+
23+
always @(posedge clk or reset) begin
24+
if (reset) begin
25+
ack_r <= 1'b0;
26+
end else begin
27+
ack_r <= (stb & cyc);
28+
end
29+
end
30+
31+
assign dat_r = dat_w;
32+
33+
WishboneInitiatorBFM init_bfm(
34+
.clock(clk),
35+
.reset(reset),
36+
.adr(adr),
37+
.dat_r(dat_r),
38+
.dat_w(dat_w),
39+
.stb(stb),
40+
.cyc(cyc),
41+
.ack(ack),
42+
.we(we)
43+
);
44+
45+
initial begin
46+
automatic Test test;
47+
48+
pyhdl_if_start();
49+
50+
#50ns;
51+
reset = 0;
52+
53+
// Create an instance of the Test class and run
54+
$display("%0t --> run", $time);
55+
test = new();
56+
test.run(init_bfm.m_api_obj.m_obj);
57+
$display("%0t <-- run", $time);
58+
$finish;
59+
end
60+
61+
endmodule
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
2+
module WishboneInitiatorBFM(
3+
input clock,
4+
input reset,
5+
output reg[31:0] adr,
6+
output reg[31:0] dat_w,
7+
input[31:0] dat_r,
8+
output cyc,
9+
input err,
10+
output reg[3:0] sel,
11+
output stb,
12+
input ack,
13+
output reg we
14+
);
15+
import call_sv_bfm_pkg::*;
16+
17+
reg [31:0] bfm_dat_w, bfm_dat_r, bfm_adr;
18+
reg[3:0] bfm_sel;
19+
reg bfm_we, bfm_req, bfm_ack;
20+
reg state;
21+
assign stb = (state == 1'b1);
22+
assign cyc = (state == 1'b1);
23+
always @(posedge clock or reset) begin
24+
if (reset) begin
25+
bfm_dat_w = {32{1'b0}};
26+
bfm_dat_r = {32{1'b0}};
27+
bfm_adr = {32{1'b0}};
28+
bfm_sel = {4{1'b0}};
29+
bfm_we = 1'b0;
30+
bfm_req = 1'b0;
31+
bfm_ack = 1'b0;
32+
state <= 1'b0;
33+
end else begin
34+
case (state)
35+
1'b0: begin
36+
if (bfm_req) begin
37+
sel <= bfm_sel;
38+
we <= bfm_we;
39+
adr <= bfm_adr;
40+
dat_w <= bfm_dat_w;
41+
bfm_req = 0;
42+
state <= 1'b1;
43+
end
44+
end
45+
1'b1: begin
46+
if (cyc && stb && ack) begin
47+
bfm_dat_r = dat_r;
48+
bfm_ack = 1;
49+
state <= 1'b0;
50+
end
51+
end
52+
endcase
53+
end
54+
end
55+
56+
57+
task bfm_write(int unsigned adr_v, int unsigned dat_v);
58+
while (bfm_req === 1'b1) begin
59+
@(posedge clock);
60+
end
61+
bfm_adr = adr_v;
62+
bfm_we = 1'b1;
63+
bfm_sel = {4{1'b1}};
64+
bfm_dat_w = dat_v;
65+
bfm_req = 1'b1;
66+
while (bfm_ack === 1'b0) begin
67+
@(posedge clock);
68+
end
69+
bfm_ack = 1'b0;
70+
endtask
71+
72+
task bfm_read(output int unsigned dat_v, input int unsigned adr_v);
73+
while (bfm_req === 1'b1) begin
74+
@(posedge clock);
75+
end
76+
bfm_adr = adr_v;
77+
bfm_we = 1'b0;
78+
bfm_sel = {4{1'b0}};
79+
//bfm_dat_w = {32{1'b0}}; // commented out to persist value
80+
bfm_req = 1'b1;
81+
while (bfm_ack === 1'b0) begin
82+
@(posedge clock);
83+
end
84+
dat_v = bfm_dat_r;
85+
bfm_ack = 1'b0;
86+
endtask
87+
88+
class WishboneInitiatorImpl extends WishboneInitiator;
89+
virtual task write(int unsigned addr, int unsigned data);
90+
$display("write");
91+
$display("--> write");
92+
bfm_write(addr, data);
93+
$display("<-- write");
94+
#10ns;
95+
endtask
96+
97+
virtual task read(output int unsigned retval, input int unsigned addr);
98+
$display("--> read");
99+
bfm_read(retval, addr);
100+
$display("<-- read (addr,data): %0d,%0d ", addr, retval);
101+
endtask
102+
103+
virtual task is_eq_hello(output bit __retval, input string val);
104+
$display("is_eq_hello: %0s", val);
105+
if (val == "hello") begin
106+
$display("eq");
107+
__retval = 1'b1;
108+
end else begin
109+
$display("neq");
110+
__retval = 1'b0;
111+
end
112+
endtask
113+
114+
endclass
115+
116+
WishboneInitiatorImpl m_api_obj;
117+
118+
// Register ourselves with the PyHDL-IF object registry
119+
initial begin : init
120+
m_api_obj = new();
121+
$display("Path: %m");
122+
pyhdl_if::pyhdl_if_registerObject(m_api_obj.m_obj, $sformatf("%m"), 1);
123+
end
124+
endmodule

tests/unit/test_smoke.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
os.path.dirname(os.path.abspath(__file__)),
1515
"data")
1616
test_smoke_data_dir = os.path.join(data_dir, "test_smoke")
17+
test_smoke_str_data_dir = os.path.join(data_dir, "test_smoke_str")
1718

1819

1920
def test_smoke(dirconfig : pfv.DirConfig):
@@ -57,3 +58,43 @@ def test_smoke(dirconfig : pfv.DirConfig):
5758

5859
assert status.startswith("PASS:")
5960

61+
def test_smoke_str(dirconfig : pfv.DirConfig):
62+
flow = pfv.FlowSim(dirconfig)
63+
64+
print("test_smoke_data_dir: %s" % test_smoke_str_data_dir, flush=True)
65+
66+
flow.addTaskToPhase("generate.main", pfv.TaskCmd("gen-api",
67+
cmd=[sys.executable, "-m", "hdl_if", "api-gen-sv", "-m", "call_sv_bfm",
68+
"--package", "call_sv_bfm_pkg", "-o", "call_sv_bfm_pkg.sv"],
69+
env=[pfv.EnvAction.prepend_path("PYTHONPATH", test_smoke_str_data_dir)],
70+
cwd=dirconfig.builddir()
71+
))
72+
flow.fs.add_library(hdl_if.share())
73+
flow.sim.addFileset(pfv.FSVlnv("fvutils::pyhdl-if", "systemVerilogSource"))
74+
75+
flow.sim.addFileset(pfv.FSPaths(
76+
dirconfig.builddir(),
77+
["call_sv_bfm_pkg.sv"],
78+
"systemVerilogSource"))
79+
80+
flow.sim.addFileset(pfv.FSPaths(
81+
test_smoke_str_data_dir,
82+
["wb_init_bfm.sv", "call_sv_bfm.sv"],
83+
"systemVerilogSource"))
84+
85+
flow.sim.dpi_libs.append(hdl_if.get_entry())
86+
flow.sim.top.add("call_sv_bfm")
87+
88+
run_args = flow.sim.mkRunArgs(dirconfig.rundir())
89+
run_args.prepend_pathenv("PYTHONPATH", test_smoke_str_data_dir)
90+
flow.addTaskToPhase("run.main", flow.sim.mkRunTask(run_args))
91+
92+
if dirconfig.config.getHdlSim() in SKIP_HDLSIM:
93+
pytest.skip("Unsupported simulator %s" % dirconfig.config.getHdlSim())
94+
else:
95+
flow.run_all()
96+
97+
with open(os.path.join(dirconfig.rundir(), "status.txt"), "r") as fp:
98+
status = fp.read().strip()
99+
100+
assert status.startswith("PASS:")

0 commit comments

Comments
 (0)