mirror of
https://github.com/YosysHQ/yosys
synced 2025-08-08 04:01:25 +00:00
commit
5c5881695d
11 changed files with 1767 additions and 0 deletions
1
tests/rpc/.gitignore
vendored
Normal file
1
tests/rpc/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*.log
|
8
tests/rpc/design.v
Normal file
8
tests/rpc/design.v
Normal file
|
@ -0,0 +1,8 @@
|
|||
module top(input [3:0] i, output [3:0] o);
|
||||
python_inv #(
|
||||
.width(4)
|
||||
) inv (
|
||||
.i(i),
|
||||
.o(o),
|
||||
);
|
||||
endmodule
|
5
tests/rpc/exec.ys
Normal file
5
tests/rpc/exec.ys
Normal file
|
@ -0,0 +1,5 @@
|
|||
connect_rpc -exec python3 frontend.py stdio
|
||||
read_verilog design.v
|
||||
hierarchy -top top
|
||||
flatten
|
||||
select -assert-count 1 t:$neg
|
126
tests/rpc/frontend.py
Normal file
126
tests/rpc/frontend.py
Normal file
|
@ -0,0 +1,126 @@
|
|||
def modules():
|
||||
return ["python_inv"]
|
||||
|
||||
def derive(module, parameters):
|
||||
assert module == r"python_inv"
|
||||
if parameters.keys() != {r"\width"}:
|
||||
raise ValueError("Invalid parameters")
|
||||
return "ilang", r"""
|
||||
module \impl
|
||||
wire width {width:d} input 1 \i
|
||||
wire width {width:d} output 2 \o
|
||||
cell $neg $0
|
||||
parameter \A_SIGNED 1'0
|
||||
parameter \A_WIDTH 32'{width:b}
|
||||
parameter \Y_WIDTH 32'{width:b}
|
||||
connect \A \i
|
||||
connect \Y \o
|
||||
end
|
||||
end
|
||||
module \python_inv
|
||||
wire width {width:d} input 1 \i
|
||||
wire width {width:d} output 2 \o
|
||||
cell \impl $0
|
||||
connect \i \i
|
||||
connect \o \o
|
||||
end
|
||||
end
|
||||
""".format(width=parameters[r"\width"])
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
import json
|
||||
import argparse
|
||||
import sys, socket, os
|
||||
try:
|
||||
import msvcrt, win32pipe, win32file
|
||||
except ImportError:
|
||||
msvcrt = win32pipe = win32file = None
|
||||
|
||||
def map_parameter(parameter):
|
||||
if parameter["type"] == "unsigned":
|
||||
return int(parameter["value"], 2)
|
||||
if parameter["type"] == "signed":
|
||||
width = len(parameter["value"])
|
||||
value = int(parameter["value"], 2)
|
||||
if value & (1 << (width - 1)):
|
||||
value = -((1 << width) - value)
|
||||
return value
|
||||
if parameter["type"] == "string":
|
||||
return parameter["value"]
|
||||
if parameter["type"] == "real":
|
||||
return float(parameter["value"])
|
||||
|
||||
def call(input_json):
|
||||
input = json.loads(input_json)
|
||||
if input["method"] == "modules":
|
||||
return json.dumps({"modules": modules()})
|
||||
if input["method"] == "derive":
|
||||
try:
|
||||
frontend, source = derive(input["module"],
|
||||
{name: map_parameter(value) for name, value in input["parameters"].items()})
|
||||
return json.dumps({"frontend": frontend, "source": source})
|
||||
except ValueError as e:
|
||||
return json.dumps({"error": str(e)})
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
modes = parser.add_subparsers(dest="mode")
|
||||
mode_stdio = modes.add_parser("stdio")
|
||||
if os.name == "posix":
|
||||
mode_path = modes.add_parser("unix-socket")
|
||||
if os.name == "nt":
|
||||
mode_path = modes.add_parser("named-pipe")
|
||||
mode_path.add_argument("path")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.mode == "stdio":
|
||||
while True:
|
||||
input = sys.stdin.readline()
|
||||
if not input: break
|
||||
sys.stdout.write(call(input) + "\n")
|
||||
sys.stdout.flush()
|
||||
|
||||
if args.mode == "unix-socket":
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
sock.bind(args.path)
|
||||
try:
|
||||
sock.listen(1)
|
||||
conn, addr = sock.accept()
|
||||
file = conn.makefile("rw")
|
||||
while True:
|
||||
input = file.readline()
|
||||
if not input: break
|
||||
file.write(call(input) + "\n")
|
||||
file.flush()
|
||||
finally:
|
||||
sock.close()
|
||||
os.unlink(args.path)
|
||||
|
||||
if args.mode == "named-pipe":
|
||||
pipe = win32pipe.CreateNamedPipe(args.path, win32pipe.PIPE_ACCESS_DUPLEX,
|
||||
win32pipe.PIPE_TYPE_BYTE|win32pipe.PIPE_READMODE_BYTE|win32pipe.PIPE_WAIT,
|
||||
1, 4096, 4096, 0, None)
|
||||
win32pipe.ConnectNamedPipe(pipe, None)
|
||||
try:
|
||||
while True:
|
||||
input = b""
|
||||
while not input.endswith(b"\n"):
|
||||
result, data = win32file.ReadFile(pipe, 4096)
|
||||
assert result == 0
|
||||
input += data
|
||||
assert not b"\n" in input or input.endswith(b"\n")
|
||||
output = (call(input.decode("utf-8")) + "\n").encode("utf-8")
|
||||
length = len(output)
|
||||
while length > 0:
|
||||
result, done = win32file.WriteFile(pipe, output)
|
||||
assert result == 0
|
||||
length -= done
|
||||
except win32file.error as e:
|
||||
if e.args[0] == 109: # ERROR_BROKEN_PIPE
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
6
tests/rpc/run-test.sh
Executable file
6
tests/rpc/run-test.sh
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
for x in *.ys; do
|
||||
echo "Running $x.."
|
||||
../../yosys -ql ${x%.ys}.log $x
|
||||
done
|
6
tests/rpc/unix.ys
Normal file
6
tests/rpc/unix.ys
Normal file
|
@ -0,0 +1,6 @@
|
|||
!python3 frontend.py unix-socket frontend.sock & sleep 0.1
|
||||
connect_rpc -path frontend.sock
|
||||
read_verilog design.v
|
||||
hierarchy -top top
|
||||
flatten
|
||||
select -assert-count 1 t:$neg
|
Loading…
Add table
Add a link
Reference in a new issue