This commit is contained in:
SunnyChen 2020-05-06 11:46:43 +08:00
parent dc423dd265
commit 6551b78d05
251 changed files with 5868 additions and 6669 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -1,18 +0,0 @@
check:
pycodestyle .
flake8 .
test:
pytest -v --cov
cov: test
codecov
clean:
rm -rf .eggs dist py_hcl.egg-info .coverage .pytest_cache */__pycache__
upload: test
python setup.py sdist && twine upload dist/*

BIN
example/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,15 @@
circuit FullAdder :
module FullAdder :
input clock : Clock
input reset : UInt<1>
output io : {flip a : UInt<1>, flip b : UInt<1>, flip cin : UInt<1>, s : UInt<1>, cout : UInt<1>}
node _T = xor(io.a, io.b)
node _T_1 = xor(_T, io.cin)
io.s <= _T_1
node _T_2 = and(io.a, io.b)
node _T_3 = and(io.a, io.cin)
node _T_4 = or(_T_2, _T_3)
node _T_5 = and(io.b, io.cin)
node _T_6 = or(_T_4, _T_5)
io.cout <= _T_6

View File

@ -0,0 +1,22 @@
module FullAdder(
input clock,
input reset,
input io_a,
input io_b,
input io_cin,
output io_s,
output io_cout
);
wire _T;
wire _T_2;
wire _T_3;
wire _T_4;
wire _T_5;
assign _T = io_a ^ io_b;
assign _T_2 = io_a & io_b;
assign _T_3 = io_a & io_cin;
assign _T_4 = _T_2 | _T_3;
assign _T_5 = io_b & io_cin;
assign io_s = _T ^ io_cin;
assign io_cout = _T_4 | _T_5;
endmodule

10
example/.fir/PC.fir Normal file
View File

@ -0,0 +1,10 @@
circuit PC :
module PC :
input clock : Clock
input reset : UInt<1>
output io : {flip pc_in : UInt<32>, pc_out : UInt<32>}
reg pc : UInt<32>, clock with :
reset => (reset, UInt<32>("h0"))
pc <= io.pc_in
io.pc_out <= pc

55
example/.fir/PC.fir.v Normal file
View File

@ -0,0 +1,55 @@
module PC(
input clock,
input reset,
input [31:0] io_pc_in,
output [31:0] io_pc_out
);
reg [31:0] pc;
reg [31:0] _RAND_0;
assign io_pc_out = pc;
`ifdef RANDOMIZE_GARBAGE_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_INVALID_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_REG_INIT
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_MEM_INIT
`define RANDOMIZE
`endif
`ifndef RANDOM
`define RANDOM $random
`endif
`ifdef RANDOMIZE_MEM_INIT
integer initvar;
`endif
`ifndef SYNTHESIS
initial begin
`ifdef RANDOMIZE
`ifdef INIT_RANDOM
`INIT_RANDOM
`endif
`ifndef VERILATOR
`ifdef RANDOMIZE_DELAY
#`RANDOMIZE_DELAY begin end
`else
#0.002 begin end
`endif
`endif
`ifdef RANDOMIZE_REG_INIT
_RAND_0 = {1{`RANDOM}};
pc = _RAND_0[31:0];
`endif // RANDOMIZE_REG_INIT
`endif // RANDOMIZE
end // initial
`endif // SYNTHESIS
always @(posedge clock) begin
if (reset) begin
pc <= 32'h0;
end else begin
pc <= io_pc_in;
end
end
endmodule

30
example/.fir/filter.fir Normal file
View File

@ -0,0 +1,30 @@
circuit MyManyDynamicElementVecFir :
module MyManyDynamicElementVecFir :
input clock : Clock
input reset : UInt<1>
output io : {flip i : UInt<8>, flip valid : UInt<1>, o : UInt<8>}
reg _T : UInt<8>, clock with :
reset => (reset, UInt<8>("h0"))
when io.valid :
_T <= io.i
reg _T_1 : UInt<8>, clock with :
reset => (reset, UInt<8>("h0"))
when io.valid :
_T_1 <= _T
reg a : UInt<8>, clock with :
reset => (reset, UInt<8>("h0"))
when io.valid :
a <= _T_1
reg b : UInt<8>, clock with :
reset => (reset, UInt<8>("h0"))
when io.valid :
b <= a
node _T_2 = mul(io.i, UInt<1>("h0"))
node _T_3 = mul(_T, UInt<1>("h1"))
node _T_4 = add(_T_2, _T_3)
node _T_5 = mul(_T_1, UInt<2>("h2"))
node _T_6 = add(_T_4, _T_5)
node _T_7 = mul(a, UInt<2>("h3"))
node _T_8 = add(_T_6, _T_7)
io.o <= bits(_T_8, 7, 0)

94
example/.fir/filter.fir.v Normal file
View File

@ -0,0 +1,94 @@
module MyManyDynamicElementVecFir(
input clock,
input reset,
input [7:0] io_i,
input io_valid,
output [7:0] io_o
);
reg [7:0] _T;
reg [31:0] _RAND_0;
reg [7:0] _T_1;
reg [31:0] _RAND_1;
reg [7:0] a;
reg [31:0] _RAND_2;
wire [8:0] _T_2;
wire [8:0] _T_3;
wire [9:0] _T_4;
wire [9:0] _T_5;
wire [10:0] _T_6;
wire [9:0] _T_7;
wire [10:0] _GEN_4;
wire [11:0] _T_8;
assign _T_2 = io_i * 8'h0;
assign _T_3 = _T * 8'h1;
assign _T_4 = _T_2 + _T_3;
assign _T_5 = _T_1 * 8'h2;
assign _T_6 = _T_4 + _T_5;
assign _T_7 = a * 8'h3;
assign _GEN_4 = {{1'd0}, _T_7};
assign _T_8 = _T_6 + _GEN_4;
assign io_o = _T_8[7:0];
`ifdef RANDOMIZE_GARBAGE_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_INVALID_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_REG_INIT
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_MEM_INIT
`define RANDOMIZE
`endif
`ifndef RANDOM
`define RANDOM $random
`endif
`ifdef RANDOMIZE_MEM_INIT
integer initvar;
`endif
`ifndef SYNTHESIS
initial begin
`ifdef RANDOMIZE
`ifdef INIT_RANDOM
`INIT_RANDOM
`endif
`ifndef VERILATOR
`ifdef RANDOMIZE_DELAY
#`RANDOMIZE_DELAY begin end
`else
#0.002 begin end
`endif
`endif
`ifdef RANDOMIZE_REG_INIT
_RAND_0 = {1{`RANDOM}};
_T = _RAND_0[7:0];
`endif // RANDOMIZE_REG_INIT
`ifdef RANDOMIZE_REG_INIT
_RAND_1 = {1{`RANDOM}};
_T_1 = _RAND_1[7:0];
`endif // RANDOMIZE_REG_INIT
`ifdef RANDOMIZE_REG_INIT
_RAND_2 = {1{`RANDOM}};
a = _RAND_2[7:0];
`endif // RANDOMIZE_REG_INIT
`endif // RANDOMIZE
end // initial
`endif // SYNTHESIS
always @(posedge clock) begin
if (reset) begin
_T <= 8'h0;
end else if (io_valid) begin
_T <= io_i;
end
if (reset) begin
_T_1 <= 8'h0;
end else if (io_valid) begin
_T_1 <= _T;
end
if (reset) begin
a <= 8'h0;
end else if (io_valid) begin
a <= _T_1;
end
end
endmodule

26
example/.fir/test.fir Normal file
View File

@ -0,0 +1,26 @@
circuit Test :
module Test :
input clock : Clock
input reset : UInt<1>
output io : {DIO_stop : UInt<1>, Jotaro_stop : UInt<1>}
reg counter : UInt<32>, clock with :
reset => (reset, UInt<32>("h0"))
node _T = add(counter, UInt<1>("h1"))
counter <= _T
node _T_1 = eq(counter, UInt<4>("ha"))
reg DIO_stop_r : UInt<1>, clock with :
reset => (reset, UInt<1>("h1"))
when _T_1 :
io.DIO_stop <= UInt<1>("h0")
DIO_stop_r <= UInt<1>("h0")
else :
io.DIO_stop <= DIO_stop_r
node _T_2 = eq(io.DIO_stop, UInt<1>("h0"))
reg Jotaro_stop_r : UInt<1>, clock with :
reset => (reset, UInt<1>("h0"))
when _T_2 :
io.Jotaro_stop <= UInt<1>("h1")
Jotaro_stop_r <= UInt<1>("h1")
else :
io.Jotaro_stop <= Jotaro_stop_r

84
example/.fir/test.fir.v Normal file
View File

@ -0,0 +1,84 @@
module Test(
input clock,
input reset,
output io_DIO_stop,
output io_Jotaro_stop
);
reg [31:0] counter;
reg [31:0] _RAND_0;
wire [32:0] _T;
wire _T_1;
reg DIO_stop_r;
reg [31:0] _RAND_1;
wire _GEN_0;
wire _T_2;
reg Jotaro_stop_r;
reg [31:0] _RAND_2;
wire _GEN_2;
assign _T = counter + 32'h1;
assign _T_1 = counter == 32'ha;
assign _GEN_0 = _T_1 ? 1'h0 : DIO_stop_r;
assign _T_2 = io_DIO_stop == 1'h0;
assign _GEN_2 = _T_2 | Jotaro_stop_r;
assign io_DIO_stop = _T_1 ? 1'h0 : DIO_stop_r;
assign io_Jotaro_stop = _T_2 | Jotaro_stop_r;
`ifdef RANDOMIZE_GARBAGE_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_INVALID_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_REG_INIT
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_MEM_INIT
`define RANDOMIZE
`endif
`ifndef RANDOM
`define RANDOM $random
`endif
`ifdef RANDOMIZE_MEM_INIT
integer initvar;
`endif
`ifndef SYNTHESIS
initial begin
`ifdef RANDOMIZE
`ifdef INIT_RANDOM
`INIT_RANDOM
`endif
`ifndef VERILATOR
`ifdef RANDOMIZE_DELAY
#`RANDOMIZE_DELAY begin end
`else
#0.002 begin end
`endif
`endif
`ifdef RANDOMIZE_REG_INIT
_RAND_0 = {1{`RANDOM}};
counter = _RAND_0[31:0];
`endif // RANDOMIZE_REG_INIT
`ifdef RANDOMIZE_REG_INIT
_RAND_1 = {1{`RANDOM}};
DIO_stop_r = _RAND_1[0:0];
`endif // RANDOMIZE_REG_INIT
`ifdef RANDOMIZE_REG_INIT
_RAND_2 = {1{`RANDOM}};
Jotaro_stop_r = _RAND_2[0:0];
`endif // RANDOMIZE_REG_INIT
`endif // RANDOMIZE
end // initial
`endif // SYNTHESIS
always @(posedge clock) begin
if (reset) begin
counter <= 32'h0;
end else begin
counter <= _T[31:0];
end
DIO_stop_r <= reset | _GEN_0;
if (reset) begin
Jotaro_stop_r <= 1'h0;
end else begin
Jotaro_stop_r <= _GEN_2;
end
end
endmodule

67
example/ALU.py Normal file
View File

@ -0,0 +1,67 @@
from pyhcl import *
from pyhcl.simulator import Simulator
class ALU_Op:
ALU_ADD = U(0)
ALU_SUB = U(1)
ALU_AND = U(2)
ALU_OR = U(3)
class ALU(Module):
io = IO(
a=Input(U.w(32)),
b=Input(U.w(32)),
ctl=Input(U.w(2)),
out=Output(U.w(32)),
)
io.out <<= LookUpTable(io.ctl, {
ALU_Op.ALU_ADD: io.a + io.b,
ALU_Op.ALU_SUB: io.a - io.b,
ALU_Op.ALU_AND: io.a & io.b,
ALU_Op.ALU_OR: io.a | io.b,
...: U(0)
})
class ALU2(Module):
io = IO(
inst=Input(U.w(32)),
a=Input(U.w(32)),
b=Input(U.w(32)),
v=Input(Vec(4, U.w(32))),
out=Output(U.w(32)),
)
sum = Sum(io.v)
lut = LookUpTable(io.inst, {
U.w(32)(10): VecInit([io.a * io.b, io.a / io.b, io.a ^ io.b, io.a % io.b]),
U.w(32)(11): VecInit([io.a == io.b, io.a != io.b, io.a < io.b, io.a > io.b]),
...: VecInit([io.a + io.b, io.a - io.b, io.a & io.b, io.a | io.b])
})
io.out <<= Sum(lut) + sum
def main():
s = Simulator(ALU())
handler = s.handler
# ---------- Simulation begin ---------- #
s.start()
for i in range(4):
s.poke(handler.io.a, 200)
s.poke(handler.io.b, 100)
s.poke(handler.io.ctl, i)
s.step()
s.peek(handler.io.out)
s.term()
# ---------- Simulation end ---------- #
if __name__ == '__main__':
main()

74
example/Adder.py Normal file
View File

@ -0,0 +1,74 @@
from pyhcl import *
from pyhcl.simulator import Simulator
class FullAdder(Module):
io = IO(
a=Input(Bool),
b=Input(Bool),
cin=Input(Bool),
sum=Output(Bool),
cout=Output(Bool),
)
# Generate the sum
a_xor_b = io.a ^ io.b
io.sum <<= a_xor_b ^ io.cin
# Generate the carry
a_and_b = io.a & io.b
b_and_cin = io.b & io.cin
a_and_cin = io.a & io.cin
io.cout <<= a_and_b | b_and_cin | a_and_cin
def adder(n: int):
class Adder(Module):
io = IO(
a=Input(U.w(n)),
b=Input(U.w(n)),
cin=Input(Bool),
sum=Output(U.w(n)),
cout=Output(Bool),
)
FAs = [FullAdder().io for _ in range(n)]
carry = Wire(Vec(n + 1, Bool))
sum = Wire(Vec(n, Bool))
carry[0] <<= io.cin
for i in range(n):
FAs[i].a <<= io.a[i]
FAs[i].b <<= io.b[i]
FAs[i].cin <<= carry[i]
carry[i + 1] <<= FAs[i].cout
sum[i] <<= FAs[i].sum
io.sum <<= CatVecH2L(sum)
io.cout <<= carry[n]
return Adder()
def main():
s = Simulator(adder(8))
handler = s.handler
# ---------- Simulation begin ---------- #
s.start()
for i in range(16):
s.poke(handler.io.a, i)
s.poke(handler.io.b, i + 1)
s.poke(handler.io.cin, i % 2)
s.step()
s.peek(handler.io.sum)
s.peek(handler.io.cout)
s.term()
# ---------- Simulation end ---------- #
if __name__ == '__main__':
main()

48
example/Adder_Buf.py Normal file
View File

@ -0,0 +1,48 @@
from pyhcl import *
class Addr_Buffer(Module):
io = IO(
addr_input=Input(U.w(32)),
flush=Input(Bool),
record=Input(Bool),
front=Output(U.w(32)),
)
buffer = Mem(3, U.w(32))
counter = Mem(3, U.w(2))
is_used = Mem(3, Bool)
io.front <<= Mux(counter[U(0)] > counter[U(1)],
Mux(counter[U(0)] > counter[U(2)], buffer[U(0)], buffer[U(2)]),
Mux(counter[U(1)] > counter[U(2)], buffer[U(1)], buffer[U(2)]))
write_index = Mux(is_used[U(0)] == U(0), U(0), Mux(is_used[U(1)] == U(0), U(1), U(2)))
temp_used_list = []
for i in range(0, 3):
temp_used_list.append(Mux(io.record.to_bool(), Mux(write_index == U(i), Bool(1), is_used[U(i)]),
is_used[U(i)]))
for i in range(0, 3):
is_used[U(i)] <<= Mux(io.flush.to_bool(), Bool(0), Mux(counter[U(i)] == U(2), Bool(0), temp_used_list[i]))
for i in range(0, 3):
counter[U(i)] <<= Mux(io.flush.to_bool(), U(0),
Mux(counter[U(i)] == U(2), U(0),
Mux(is_used[U(i)], counter[U(i)] + U(1), counter[U(i)])))
for i in range(0, 3):
buffer[U(i)] <<= Mux(io.flush.to_bool(), U(0),
Mux(counter[U(i)] == U(2), U(0),
Mux(io.record.to_bool(),
Mux(write_index == U(i), io.addr_input, buffer[U(i)]), buffer[U(i)])))
def main():
Emitter.dumpVerilog(Emitter.dump(Emitter.emit(Addr_Buffer()), "adder_buf.dir"))
if __name__ == '__main__':
main()

77
example/Bitpat.py Normal file
View File

@ -0,0 +1,77 @@
from pyhcl import *
class Inst:
ADD = BitPat("0000000??????????000?????0110011")
SUB = BitPat("0100000??????????000?????0110011")
AND = BitPat("0000000??????????111?????0110011")
OR = BitPat("0000000??????????110?????0110011")
LW = BitPat("?????????????????010?????0000011")
SW = BitPat("?????????????????010?????0100011")
class Control:
# ALUOP
ALUOP_XXX = U(0)
ALUOP_ADD = U(0)
ALUOP_SUB = U(1)
ALUOP_AND = U(2)
ALUOP_OR = U(3)
# MEM_READ
MEM_READ_FALSE = U(0)
MEM_READ_TRUE = U(1)
# MEM_WRITE
MEM_WRITE_FALSE = U(0)
MEM_WRITE_TRUE = U(1)
# REG_WRITE
REG_WRITE_FALSE = U(0)
REG_WRITE_TRUE = U(1)
# map dict
map = {
Inst.ADD: VecInit([ALUOP_ADD, MEM_READ_FALSE, MEM_WRITE_FALSE, REG_WRITE_TRUE]),
Inst.SUB: VecInit([ALUOP_SUB, MEM_READ_FALSE, MEM_WRITE_FALSE, REG_WRITE_TRUE]),
Inst.AND: VecInit([ALUOP_AND, MEM_READ_FALSE, MEM_WRITE_FALSE, REG_WRITE_TRUE]),
Inst.OR: VecInit([ALUOP_OR, MEM_READ_FALSE, MEM_WRITE_FALSE, REG_WRITE_TRUE]),
Inst.LW: VecInit([ALUOP_XXX, MEM_READ_TRUE, MEM_WRITE_FALSE, REG_WRITE_TRUE]),
Inst.SW: VecInit([ALUOP_XXX, MEM_READ_FALSE, MEM_WRITE_TRUE, REG_WRITE_FALSE]),
...: VecInit([ALUOP_XXX, MEM_READ_FALSE, MEM_WRITE_FALSE, REG_WRITE_FALSE])
}
class BitPadTest(Module):
io = IO(
inst=Input(U.w(32)),
ALUOP=Output(U.w(32)),
MEM_READ=Output(U.w(32)),
MEM_WRITE=Output(U.w(32)),
REG_WRITE=Output(U.w(32)),
a=Input(U.w(32)),
b=Input(U.w(32)),
v=Input(Vec(4, U.w(32))),
out=Output(U.w(32)),
)
stmt_list = LookUpTable(io.inst, {
Inst.ADD: VecInit([io.a * io.b, io.a / io.b, io.a ^ io.b, io.a % io.b]),
Inst.SUB: VecInit([io.a == io.b, io.a != io.b, io.a < io.b, io.a > io.b]),
...: VecInit([io.a + io.b, io.a - io.b, io.a & io.b, io.a | io.b])
})
sum = Sum(io.v)
io.out <<= Sum(stmt_list) + sum
ctrl_signal = LookUpTable(io.inst, Control.map)
v = VecInit([io.ALUOP, io.MEM_READ, io.MEM_WRITE, io.REG_WRITE])
v <<= ctrl_signal
if __name__ == '__main__':
f = Emitter.dump(Emitter.emit(BitPadTest()), "bitpat.dir")
Emitter.dumpVerilog(f)

25
example/Blackbox.py Normal file
View File

@ -0,0 +1,25 @@
from pyhcl import *
class BBox(BlackBox):
io = IO(
in1=Input(U.w(64)),
in2=Input(U.w(64)),
out=Output(U.w(64)),
)
class M(Module):
io = IO(
i = Input(U.w(64)),
o = Output(U.w(64)),
)
bbox = BBox()
bbox.io.in1 <<= io.i
bbox.io.in2 <<= io.i
io.o <<= bbox.io.out
if __name__ == '__main__':
Emitter.dumpVerilog(Emitter.dump(Emitter.emit(M()), "bbox.fir"))

35
example/Filter.py Normal file
View File

@ -0,0 +1,35 @@
from functools import reduce
from typing import List
from pyhcl import *
def myManyDynamicElementVecFir(length: int, consts: List):
class MyManyDynamicElementVecFir(Module):
io = IO(
i=Input(U.w(8)),
valid=Input(Bool),
o=Output(U.w(8)),
)
taps = [io.i] + [RegInit(U.w(8)(0)) for _ in range(length)]
for a, b in zip(taps, taps[1:]):
with when(io.valid):
b <<= a
m = map(lambda x: x[0] * x[1], zip(taps, consts))
io.o <<= reduce(lambda x, y: x + y, m)
return MyManyDynamicElementVecFir()
def main():
consts = []
for i in range(4):
consts.append(U(i))
f = Emitter.dump(Emitter.emit(myManyDynamicElementVecFir(4, consts)), "filter.fir")
Emitter.dumpVerilog(f)
if __name__ == '__main__':
main()

18
example/Full_Adder.py Normal file
View File

@ -0,0 +1,18 @@
from pyhcl import *
class FullAdder(Module):
io = IO(
a=Input(U.w(1)),
b=Input(U.w(1)),
cin=Input(U.w(1)),
s=Output(U.w(1)),
cout=Output(U.w(1))
)
io.s <<= io.a ^ io.b ^ io.cin
io.cout <<= (io.a & io.b) | (io.a & io.cin) | (io.b & io.cin)
if __name__ == '__main__':
Emitter.dumpVerilog(Emitter.dump(Emitter.emit(FullAdder()), "FullAdder.fir"))

35
example/GCD.py Normal file
View File

@ -0,0 +1,35 @@
from pyhcl import *
class GCD(Module):
io = IO(
a=Input(U.w(32)),
b=Input(U.w(32)),
e=Input(Bool),
z=Output(U.w(32)),
v=Output(Bool),
)
x = Reg(U.w(32))
y = Reg(U.w(32))
with when(x > y):
x <<= x - y
with otherwise():
y <<= y - x
with when(io.e):
x <<= io.a
y <<= io.b
io.z <<= x
io.v <<= y == U(0)
def main():
f = Emitter.dump(Emitter.emit(GCD()), "gcd.fir")
Emitter.dumpVerilog(f)
if __name__ == '__main__':
main()

40
example/MatrixMul.py Normal file
View File

@ -0,0 +1,40 @@
from pyhcl import *
def matrixMul(x: int, y: int, z: int, width: int):
class MatrixMul(Module):
io = IO(
a=Input(Vec(x, Vec(y, U.w(width)))),
b=Input(Vec(y, Vec(z, U.w(width)))),
o=Output(Vec(x, Vec(z, U.w(width)))),
v=Output(Bool)
)
counter = RegInit(U.w(32)(0))
res = Reg(Vec(x, Vec(z, U.w(width))))
io.v <<= Bool(False)
io.o <<= res
with when(counter == U(x * z)):
counter <<= U(0)
io.v <<= Bool(True)
with otherwise():
counter <<= counter + U(1)
row = counter / U(x)
col = counter % U(x)
res[row][col] <<= (lambda io, row, col: Sum(io.a[row][i] * io.b[i][col] for i in range(y)))(io, row, col)
# # a trick of solving python3 closure scope problem
# io.o <<= (lambda io: VecInit(VecInit(
# Sum(a * b for a, b in zip(a_row, b_col)) for b_col in zip(*io.b)) for a_row in io.a))(io)
return MatrixMul()
def main():
Emitter.dumpVerilog(Emitter.dump(Emitter.emit(matrixMul(2, 3, 2, 8)), "matrixMul.fir"))
if __name__ == '__main__':
main()

32
example/MaxN.py Normal file
View File

@ -0,0 +1,32 @@
from functools import reduce
from pyhcl import *
def maxN(n: int, w: int):
def _max2(x: U, y: U):
return Mux(x > y, x, y)
class MaxN(Module):
io = IO(
ins=Input(Vec(n, U.w(w))),
out=Output(U.w(w)),
)
io.out <<= reduce(_max2, io.ins)
# temp = io.ins[0]
# for x in io.ins[1:]:
# temp = Mux(temp > x, temp, x)
# io.out <<= temp
return MaxN()
def main():
f = Emitter.dump(Emitter.emit(maxN(16, 32)), "maxN.fir")
Emitter.dumpVerilog(f)
if __name__ == '__main__':
main()

21
example/Mem.py Normal file
View File

@ -0,0 +1,21 @@
from pyhcl import *
class MemDemo(Module):
io = IO(
i=Input(U.w(8)),
o=Output(U.w(8)),
)
m = Mem(10, U.w(8))
m[U(2)] <<= io.i
io.o <<= m[U(2)]
def main():
f = Emitter.dump(Emitter.emit(MemDemo()), "mem.fir")
Emitter.dumpVerilog(f)
if __name__ == '__main__':
main()

69
example/Mul.py Normal file
View File

@ -0,0 +1,69 @@
from pyhcl import *
class Mul1(Module):
"""
Four-by-four multiply using a look-up table.
"""
io = IO(
x=Input(U.w(4)),
y=Input(U.w(4)),
z=Output(U.w(8)),
)
# --------------------------------
# Calculate io.z = io.x * io.y by
# building filling out muls
# --------------------------------
muls = [U.w(8)(i * j) for i in range(16) for j in range(16)]
tbl = VecInit(muls)
io.z <<= tbl[io.x << U(4) | io.y]
class Mul2(Module):
"""
Four-by-four multiply using a look-up table.
"""
io = IO(
x=Input(U.w(4)),
y=Input(U.w(4)),
z=Output(U.w(8)),
)
# --------------------------------
# Calculate io.z = io.x * io.y by
# building filling out tbl
# --------------------------------
tbl = VecInit(VecInit(U.w(8)(i * j) for i in range(16)) for j in range(16))
io.z <<= tbl[io.x][io.y]
class Mul3(Module):
"""
Four-by-four multiply using a look-up table.
"""
io = IO(
x=Input(U.w(2)),
y=Input(U.w(2)),
z=Input(U.w(2)),
o=Output(U.w(6)),
)
# --------------------------------
# Calculate io.z = io.x * io.y by
# building filling out tbl
# --------------------------------
tbl = VecInit(VecInit(VecInit(U.w(6)(i * j * k) for k in range(4)) for i in range(4)) for j in range(4))
io.o <<= tbl[io.x][io.y][io.z]
def main():
f = Emitter.dump(Emitter.emit(Mul1()), "mul.fir")
Emitter.dumpVerilog(f)
if __name__ == '__main__':
main()

61
example/Neurons.py Normal file
View File

@ -0,0 +1,61 @@
from pyhcl import *
W = 8 # 位宽
def matrixMul(x: int, y: int, z: int):
"""
x*y × y*z 矩阵乘法电路
"""
class MatrixMul(Module):
io = IO(
a=Input(Vec(x, Vec(y, U.w(W)))),
b=Input(Vec(y, Vec(z, U.w(W)))),
o=Output(Vec(x, Vec(z, U.w(W)))),
)
for i, a_row in enumerate(io.a):
for j, b_col in enumerate(zip(*io.b)):
io.o[i][j] <<= Sum(a * b for a, b in zip(a_row, b_col))
return MatrixMul()
def bias(n):
return U.w(W)(n)
def weight(lst):
return VecInit(U.w(W)(i) for i in lst)
def neurons(w, b):
"""
参数权重向量 w偏移量 b
输出神经网络神经元电路 *暂无通过非线性传递函数
"""
class Unit(Module):
io = IO(
i=Input(Vec(len(w), U.w(W))),
o=Output(U.w(W))
)
m = matrixMul(1, len(w), 1).io
m.a <<= io.i
m.b <<= w
io.o <<= m.o[0][0] + b
return Unit()
def main():
# 得到权重向量为[3, 4, 5, 6, 7, 8, 9, 10]偏移量为14的神经元电路
n = neurons(weight([3, 4, 5, 6, 7, 8, 9, 10]), bias(14))
f = Emitter.dump(Emitter.emit(n), "neurons.fir")
Emitter.dumpVerilog(f)
if __name__ == '__main__':
main()

31
example/ShiftRegister.py Normal file
View File

@ -0,0 +1,31 @@
from pyhcl import *
class ShiftRegister(Module):
io = IO(
i=Input(Bool),
o=Output(Bool),
en=Input(Bool),
)
r0 = RegInit(U(0))
r1 = RegInit(U(0))
r2 = RegInit(U(0))
r3 = RegInit(U(0))
with when(io.en):
r0 <<= io.i
r1 <<= r0
r2 <<= r1
r3 <<= r2
io.o <<= r3
def main():
f = Emitter.dump(Emitter.emit(ShiftRegister()), "shiftR.fir")
Emitter.dumpVerilog(f)
if __name__ == '__main__':
main()

22
example/muxVec.py Normal file
View File

@ -0,0 +1,22 @@
from pyhcl import *
class MuxVec(Module):
io = IO(
i=Input(Bool),
o=Output(Vec(4, Vec(8, U.w(32)))),
)
a = VecInit(VecInit(U.w(32)(i) for i in range(8)) for _ in range(4))
b = VecInit(VecInit(U.w(32)(i) for i in range(7, -1, -1)) for _ in range(4))
io.o <<= Mux(io.i, a, b)
def main():
f = Emitter.dump(Emitter.emit(MuxVec()), "muxVec.fir")
Emitter.dumpVerilog(f)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,99 @@
#include "VAdder.h"
#include "simulator.h"
using namespace std;
class Adder_Simulator: public Simulator<DataWrapper*>
{
private:
VAdder* dut;
VerilatedVcdC *tfp;
int psize;
public:
Adder_Simulator(VAdder* _dut): Simulator()
{
this->dut = _dut;
this->psize = getpagesize();
}
~Adder_Simulator()
{
munmap(this->in, this->psize);
munmap(this->sig, this->psize);
munmap(this->out, this->psize);
close(this->in_fd);
close(this->out_fd);
close(this->sig_fd);
remove("./in.dat");
remove("./sig.dat");
remove("./out.dat");
}
void init_tfp(VerilatedVcdC *_tfp)
{
this->tfp = _tfp;
}
void init_simdata()
{
this->sim_datas.inputs.clear();
this->sim_datas.outputs.clear();
this->sim_datas.inputs.push_back(new CDataWrapper(&(dut->clock)));
this->sim_datas.inputs.push_back(new CDataWrapper(&(dut->reset)));
this->sim_datas.inputs.push_back(new CDataWrapper(&(dut->io_a)));
this->sim_datas.inputs.push_back(new CDataWrapper(&(dut->io_b)));
this->sim_datas.inputs.push_back(new CDataWrapper(&(dut->io_cin)));
this->sim_datas.outputs.push_back(new CDataWrapper(&(dut->io_sum)));
this->sim_datas.outputs.push_back(new CDataWrapper(&(dut->io_cout)));
}
virtual void step()
{
this->dut->clock = 0;
this->dut->eval();
this->tfp->dump(this->main_time);
this->main_time++;
this->dut->clock = 1;
this->dut->eval();
this->tfp->dump(this->main_time);
this->main_time++;
}
virtual void reset()
{
this->dut->reset = 1;
step();
}
virtual void start()
{
this->dut->reset = 0;
step();
}
};
int main(int argc, char **argv)
{
Verilated::commandArgs(argc, argv);
Verilated::traceEverOn(true);
VAdder *top = new VAdder;
VerilatedVcdC *tfp = new VerilatedVcdC;
tfp = new VerilatedVcdC;
top->trace(tfp, 99);
tfp->open("Adder.vcd");
Adder_Simulator sim(top);
sim.init_simdata();
sim.init_tfp(tfp);
top->reset = 1;
while(!sim.isexit())
sim.tick();
delete tfp;
delete top;
exit(0);
}

View File

@ -0,0 +1,113 @@
circuit Adder :
module FullAdder :
input clock : Clock
input reset : UInt<1>
output io : {flip a : UInt<1>, flip b : UInt<1>, flip cin : UInt<1>, sum : UInt<1>, cout : UInt<1>}
node a_xor_b = xor(io.a, io.b)
node _T = xor(a_xor_b, io.cin)
io.sum <= _T
node a_and_b = and(io.a, io.b)
node b_and_cin = and(io.b, io.cin)
node _T_1 = or(a_and_b, b_and_cin)
node a_and_cin = and(io.a, io.cin)
node _T_2 = or(_T_1, a_and_cin)
io.cout <= _T_2
module Adder :
input clock : Clock
input reset : UInt<1>
output io : {flip a : UInt<8>, flip b : UInt<8>, flip cin : UInt<1>, sum : UInt<8>, cout : UInt<1>}
wire carry : UInt<1>[9]
carry[0] <= io.cin
inst _T of FullAdder
_T.clock <= clock
_T.reset <= reset
node _T_1 = bits(io.a, 0, 0)
_T.io.a <= _T_1
node _T_2 = bits(io.b, 0, 0)
_T.io.b <= _T_2
_T.io.cin <= carry[0]
carry[1] <= _T.io.cout
wire sum : UInt<1>[8]
sum[0] <= _T.io.sum
inst _T_3 of FullAdder
_T_3.clock <= clock
_T_3.reset <= reset
node _T_4 = bits(io.a, 1, 1)
_T_3.io.a <= _T_4
node _T_5 = bits(io.b, 1, 1)
_T_3.io.b <= _T_5
_T_3.io.cin <= carry[1]
carry[2] <= _T_3.io.cout
sum[1] <= _T_3.io.sum
inst _T_6 of FullAdder
_T_6.clock <= clock
_T_6.reset <= reset
node _T_7 = bits(io.a, 2, 2)
_T_6.io.a <= _T_7
node _T_8 = bits(io.b, 2, 2)
_T_6.io.b <= _T_8
_T_6.io.cin <= carry[2]
carry[3] <= _T_6.io.cout
sum[2] <= _T_6.io.sum
inst _T_9 of FullAdder
_T_9.clock <= clock
_T_9.reset <= reset
node _T_10 = bits(io.a, 3, 3)
_T_9.io.a <= _T_10
node _T_11 = bits(io.b, 3, 3)
_T_9.io.b <= _T_11
_T_9.io.cin <= carry[3]
carry[4] <= _T_9.io.cout
sum[3] <= _T_9.io.sum
inst _T_12 of FullAdder
_T_12.clock <= clock
_T_12.reset <= reset
node _T_13 = bits(io.a, 4, 4)
_T_12.io.a <= _T_13
node _T_14 = bits(io.b, 4, 4)
_T_12.io.b <= _T_14
_T_12.io.cin <= carry[4]
carry[5] <= _T_12.io.cout
sum[4] <= _T_12.io.sum
inst _T_15 of FullAdder
_T_15.clock <= clock
_T_15.reset <= reset
node _T_16 = bits(io.a, 5, 5)
_T_15.io.a <= _T_16
node _T_17 = bits(io.b, 5, 5)
_T_15.io.b <= _T_17
_T_15.io.cin <= carry[5]
carry[6] <= _T_15.io.cout
sum[5] <= _T_15.io.sum
inst _T_18 of FullAdder
_T_18.clock <= clock
_T_18.reset <= reset
node _T_19 = bits(io.a, 6, 6)
_T_18.io.a <= _T_19
node _T_20 = bits(io.b, 6, 6)
_T_18.io.b <= _T_20
_T_18.io.cin <= carry[6]
carry[7] <= _T_18.io.cout
sum[6] <= _T_18.io.sum
inst _T_21 of FullAdder
_T_21.clock <= clock
_T_21.reset <= reset
node _T_22 = bits(io.a, 7, 7)
_T_21.io.a <= _T_22
node _T_23 = bits(io.b, 7, 7)
_T_21.io.b <= _T_23
_T_21.io.cin <= carry[7]
carry[8] <= _T_21.io.cout
sum[7] <= _T_21.io.sum
node _T_24 = cat(sum[7], sum[6])
node _T_25 = cat(sum[5], sum[4])
node _T_26 = cat(_T_24, _T_25)
node _T_27 = cat(sum[3], sum[2])
node _T_28 = cat(sum[1], sum[0])
node _T_29 = cat(_T_27, _T_28)
node _T_30 = cat(_T_26, _T_29)
io.sum <= _T_30
io.cout <= carry[8]

172
example/simulation/Adder.v Normal file
View File

@ -0,0 +1,172 @@
module FullAdder(
input io_a,
input io_b,
input io_cin,
output io_sum,
output io_cout
);
wire a_xor_b;
wire a_and_b;
wire b_and_cin;
wire _T_1;
wire a_and_cin;
assign a_xor_b = io_a ^ io_b;
assign a_and_b = io_a & io_b;
assign b_and_cin = io_b & io_cin;
assign _T_1 = a_and_b | b_and_cin;
assign a_and_cin = io_a & io_cin;
assign io_sum = a_xor_b ^ io_cin;
assign io_cout = _T_1 | a_and_cin;
endmodule
module Adder(
input clock,
input reset,
input [7:0] io_a,
input [7:0] io_b,
input io_cin,
output [7:0] io_sum,
output io_cout
);
wire _T_io_a;
wire _T_io_b;
wire _T_io_cin;
wire _T_io_sum;
wire _T_io_cout;
wire _T_3_io_a;
wire _T_3_io_b;
wire _T_3_io_cin;
wire _T_3_io_sum;
wire _T_3_io_cout;
wire _T_6_io_a;
wire _T_6_io_b;
wire _T_6_io_cin;
wire _T_6_io_sum;
wire _T_6_io_cout;
wire _T_9_io_a;
wire _T_9_io_b;
wire _T_9_io_cin;
wire _T_9_io_sum;
wire _T_9_io_cout;
wire _T_12_io_a;
wire _T_12_io_b;
wire _T_12_io_cin;
wire _T_12_io_sum;
wire _T_12_io_cout;
wire _T_15_io_a;
wire _T_15_io_b;
wire _T_15_io_cin;
wire _T_15_io_sum;
wire _T_15_io_cout;
wire _T_18_io_a;
wire _T_18_io_b;
wire _T_18_io_cin;
wire _T_18_io_sum;
wire _T_18_io_cout;
wire _T_21_io_a;
wire _T_21_io_b;
wire _T_21_io_cin;
wire _T_21_io_sum;
wire _T_21_io_cout;
wire sum_7;
wire sum_6;
wire sum_5;
wire sum_4;
wire [3:0] _T_26;
wire sum_3;
wire sum_2;
wire sum_1;
wire sum_0;
wire [3:0] _T_29;
FullAdder _T (
.io_a(_T_io_a),
.io_b(_T_io_b),
.io_cin(_T_io_cin),
.io_sum(_T_io_sum),
.io_cout(_T_io_cout)
);
FullAdder _T_3 (
.io_a(_T_3_io_a),
.io_b(_T_3_io_b),
.io_cin(_T_3_io_cin),
.io_sum(_T_3_io_sum),
.io_cout(_T_3_io_cout)
);
FullAdder _T_6 (
.io_a(_T_6_io_a),
.io_b(_T_6_io_b),
.io_cin(_T_6_io_cin),
.io_sum(_T_6_io_sum),
.io_cout(_T_6_io_cout)
);
FullAdder _T_9 (
.io_a(_T_9_io_a),
.io_b(_T_9_io_b),
.io_cin(_T_9_io_cin),
.io_sum(_T_9_io_sum),
.io_cout(_T_9_io_cout)
);
FullAdder _T_12 (
.io_a(_T_12_io_a),
.io_b(_T_12_io_b),
.io_cin(_T_12_io_cin),
.io_sum(_T_12_io_sum),
.io_cout(_T_12_io_cout)
);
FullAdder _T_15 (
.io_a(_T_15_io_a),
.io_b(_T_15_io_b),
.io_cin(_T_15_io_cin),
.io_sum(_T_15_io_sum),
.io_cout(_T_15_io_cout)
);
FullAdder _T_18 (
.io_a(_T_18_io_a),
.io_b(_T_18_io_b),
.io_cin(_T_18_io_cin),
.io_sum(_T_18_io_sum),
.io_cout(_T_18_io_cout)
);
FullAdder _T_21 (
.io_a(_T_21_io_a),
.io_b(_T_21_io_b),
.io_cin(_T_21_io_cin),
.io_sum(_T_21_io_sum),
.io_cout(_T_21_io_cout)
);
assign sum_7 = _T_21_io_sum;
assign sum_6 = _T_18_io_sum;
assign sum_5 = _T_15_io_sum;
assign sum_4 = _T_12_io_sum;
assign _T_26 = {sum_7,sum_6,sum_5,sum_4};
assign sum_3 = _T_9_io_sum;
assign sum_2 = _T_6_io_sum;
assign sum_1 = _T_3_io_sum;
assign sum_0 = _T_io_sum;
assign _T_29 = {sum_3,sum_2,sum_1,sum_0};
assign io_sum = {_T_26,_T_29};
assign io_cout = _T_21_io_cout;
assign _T_io_a = io_a[0];
assign _T_io_b = io_b[0];
assign _T_io_cin = io_cin;
assign _T_3_io_a = io_a[1];
assign _T_3_io_b = io_b[1];
assign _T_3_io_cin = _T_io_cout;
assign _T_6_io_a = io_a[2];
assign _T_6_io_b = io_b[2];
assign _T_6_io_cin = _T_3_io_cout;
assign _T_9_io_a = io_a[3];
assign _T_9_io_b = io_b[3];
assign _T_9_io_cin = _T_6_io_cout;
assign _T_12_io_a = io_a[4];
assign _T_12_io_b = io_b[4];
assign _T_12_io_cin = _T_9_io_cout;
assign _T_15_io_a = io_a[5];
assign _T_15_io_b = io_b[5];
assign _T_15_io_cin = _T_12_io_cout;
assign _T_18_io_a = io_a[6];
assign _T_18_io_b = io_b[6];
assign _T_18_io_cin = _T_15_io_cout;
assign _T_21_io_a = io_a[7];
assign _T_21_io_b = io_b[7];
assign _T_21_io_cin = _T_18_io_cout;
endmodule

View File

@ -0,0 +1,5 @@
Adder-harness.o: ../Adder-harness.cpp VAdder.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilatedos.h \
../simulator.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated_vcd_c.h

View File

@ -0,0 +1,281 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Design implementation internals
// See VAdder.h for the primary calling header
#include "VAdder.h"
#include "VAdder__Syms.h"
//--------------------
// STATIC VARIABLES
//--------------------
VL_CTOR_IMP(VAdder) {
VAdder__Syms* __restrict vlSymsp = __VlSymsp = new VAdder__Syms(this, name());
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
// Reset internal values
// Reset structure values
_ctor_var_reset();
}
void VAdder::__Vconfigure(VAdder__Syms* vlSymsp, bool first) {
if (0 && first) {} // Prevent unused
this->__VlSymsp = vlSymsp;
}
VAdder::~VAdder() {
delete __VlSymsp; __VlSymsp=NULL;
}
//--------------------
void VAdder::eval() {
VL_DEBUG_IF(VL_DBG_MSGF("+++++TOP Evaluate VAdder::eval\n"); );
VAdder__Syms* __restrict vlSymsp = this->__VlSymsp; // Setup global symbol table
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
#ifdef VL_DEBUG
// Debug assertions
_eval_debug_assertions();
#endif // VL_DEBUG
// Initialize
if (VL_UNLIKELY(!vlSymsp->__Vm_didInit)) _eval_initial_loop(vlSymsp);
// Evaluate till stable
int __VclockLoop = 0;
QData __Vchange = 1;
do {
VL_DEBUG_IF(VL_DBG_MSGF("+ Clock loop\n"););
vlSymsp->__Vm_activity = true;
_eval(vlSymsp);
if (VL_UNLIKELY(++__VclockLoop > 100)) {
// About to fail, so enable debug to see what's not settling.
// Note you must run make with OPT=-DVL_DEBUG for debug prints.
int __Vsaved_debug = Verilated::debug();
Verilated::debug(1);
__Vchange = _change_request(vlSymsp);
Verilated::debug(__Vsaved_debug);
VL_FATAL_MT(__FILE__,__LINE__,__FILE__,"Verilated model didn't converge");
} else {
__Vchange = _change_request(vlSymsp);
}
} while (VL_UNLIKELY(__Vchange));
}
void VAdder::_eval_initial_loop(VAdder__Syms* __restrict vlSymsp) {
vlSymsp->__Vm_didInit = true;
_eval_initial(vlSymsp);
vlSymsp->__Vm_activity = true;
// Evaluate till stable
int __VclockLoop = 0;
QData __Vchange = 1;
do {
_eval_settle(vlSymsp);
_eval(vlSymsp);
if (VL_UNLIKELY(++__VclockLoop > 100)) {
// About to fail, so enable debug to see what's not settling.
// Note you must run make with OPT=-DVL_DEBUG for debug prints.
int __Vsaved_debug = Verilated::debug();
Verilated::debug(1);
__Vchange = _change_request(vlSymsp);
Verilated::debug(__Vsaved_debug);
VL_FATAL_MT(__FILE__,__LINE__,__FILE__,"Verilated model didn't DC converge");
} else {
__Vchange = _change_request(vlSymsp);
}
} while (VL_UNLIKELY(__Vchange));
}
//--------------------
// Internal Methods
VL_INLINE_OPT void VAdder::_combo__TOP__1(VAdder__Syms* __restrict vlSymsp) {
VL_DEBUG_IF(VL_DBG_MSGF("+ VAdder::_combo__TOP__1\n"); );
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
// Body
vlTOPp->Adder__DOT___T_io_cout = (1U & ((((IData)(vlTOPp->io_a)
& (IData)(vlTOPp->io_b))
| ((IData)(vlTOPp->io_b)
& (IData)(vlTOPp->io_cin)))
| ((IData)(vlTOPp->io_a)
& (IData)(vlTOPp->io_cin))));
vlTOPp->Adder__DOT___T_3_io_cout = (1U & (((((IData)(vlTOPp->io_a)
& (IData)(vlTOPp->io_b))
>> 1U)
| (((IData)(vlTOPp->io_b)
>> 1U)
& (IData)(vlTOPp->Adder__DOT___T_io_cout)))
| (((IData)(vlTOPp->io_a)
>> 1U)
& (IData)(vlTOPp->Adder__DOT___T_io_cout))));
vlTOPp->Adder__DOT___T_6_io_cout = (1U & (((((IData)(vlTOPp->io_a)
& (IData)(vlTOPp->io_b))
>> 2U)
| (((IData)(vlTOPp->io_b)
>> 2U)
& (IData)(vlTOPp->Adder__DOT___T_3_io_cout)))
| (((IData)(vlTOPp->io_a)
>> 2U)
& (IData)(vlTOPp->Adder__DOT___T_3_io_cout))));
vlTOPp->Adder__DOT___T_9_io_cout = (1U & (((((IData)(vlTOPp->io_a)
& (IData)(vlTOPp->io_b))
>> 3U)
| (((IData)(vlTOPp->io_b)
>> 3U)
& (IData)(vlTOPp->Adder__DOT___T_6_io_cout)))
| (((IData)(vlTOPp->io_a)
>> 3U)
& (IData)(vlTOPp->Adder__DOT___T_6_io_cout))));
vlTOPp->Adder__DOT___T_12_io_cout = (1U & (((((IData)(vlTOPp->io_a)
& (IData)(vlTOPp->io_b))
>> 4U)
| (((IData)(vlTOPp->io_b)
>> 4U)
& (IData)(vlTOPp->Adder__DOT___T_9_io_cout)))
| (((IData)(vlTOPp->io_a)
>> 4U)
& (IData)(vlTOPp->Adder__DOT___T_9_io_cout))));
vlTOPp->Adder__DOT___T_15_io_cout = (1U & (((((IData)(vlTOPp->io_a)
& (IData)(vlTOPp->io_b))
>> 5U)
| (((IData)(vlTOPp->io_b)
>> 5U)
& (IData)(vlTOPp->Adder__DOT___T_12_io_cout)))
| (((IData)(vlTOPp->io_a)
>> 5U)
& (IData)(vlTOPp->Adder__DOT___T_12_io_cout))));
vlTOPp->Adder__DOT___T_18_io_cout = (1U & (((((IData)(vlTOPp->io_a)
& (IData)(vlTOPp->io_b))
>> 6U)
| (((IData)(vlTOPp->io_b)
>> 6U)
& (IData)(vlTOPp->Adder__DOT___T_15_io_cout)))
| (((IData)(vlTOPp->io_a)
>> 6U)
& (IData)(vlTOPp->Adder__DOT___T_15_io_cout))));
vlTOPp->io_cout = (1U & (((((IData)(vlTOPp->io_a)
& (IData)(vlTOPp->io_b))
>> 7U) | (((IData)(vlTOPp->io_b)
>> 7U) & (IData)(vlTOPp->Adder__DOT___T_18_io_cout)))
| (((IData)(vlTOPp->io_a)
>> 7U) & (IData)(vlTOPp->Adder__DOT___T_18_io_cout))));
vlTOPp->io_sum = ((0x80U & ((0xffffff80U & ((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b)))
^ ((IData)(vlTOPp->Adder__DOT___T_18_io_cout)
<< 7U))) | ((0x40U
& ((0xffffffc0U
& ((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b)))
^
((IData)(vlTOPp->Adder__DOT___T_15_io_cout)
<< 6U)))
| ((0x20U
& ((0xffffffe0U
& ((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b)))
^
((IData)(vlTOPp->Adder__DOT___T_12_io_cout)
<< 5U)))
| ((0x10U
& ((0xfffffff0U
& ((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b)))
^
((IData)(vlTOPp->Adder__DOT___T_9_io_cout)
<< 4U)))
| ((8U
& ((0xfffffff8U
& ((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b)))
^
((IData)(vlTOPp->Adder__DOT___T_6_io_cout)
<< 3U)))
| ((4U
& ((0xfffffffcU
& ((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b)))
^
((IData)(vlTOPp->Adder__DOT___T_3_io_cout)
<< 2U)))
| ((2U
& ((0xfffffffeU
& ((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b)))
^
((IData)(vlTOPp->Adder__DOT___T_io_cout)
<< 1U)))
| (1U
& (((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
^ (IData)(vlTOPp->io_cin))))))))));
}
void VAdder::_eval(VAdder__Syms* __restrict vlSymsp) {
VL_DEBUG_IF(VL_DBG_MSGF("+ VAdder::_eval\n"); );
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
// Body
vlTOPp->_combo__TOP__1(vlSymsp);
}
void VAdder::_eval_initial(VAdder__Syms* __restrict vlSymsp) {
VL_DEBUG_IF(VL_DBG_MSGF("+ VAdder::_eval_initial\n"); );
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
}
void VAdder::final() {
VL_DEBUG_IF(VL_DBG_MSGF("+ VAdder::final\n"); );
// Variables
VAdder__Syms* __restrict vlSymsp = this->__VlSymsp;
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
}
void VAdder::_eval_settle(VAdder__Syms* __restrict vlSymsp) {
VL_DEBUG_IF(VL_DBG_MSGF("+ VAdder::_eval_settle\n"); );
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
// Body
vlTOPp->_combo__TOP__1(vlSymsp);
}
VL_INLINE_OPT QData VAdder::_change_request(VAdder__Syms* __restrict vlSymsp) {
VL_DEBUG_IF(VL_DBG_MSGF("+ VAdder::_change_request\n"); );
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
// Body
// Change detection
QData __req = false; // Logically a bool
return __req;
}
#ifdef VL_DEBUG
void VAdder::_eval_debug_assertions() {
VL_DEBUG_IF(VL_DBG_MSGF("+ VAdder::_eval_debug_assertions\n"); );
// Body
if (VL_UNLIKELY((clock & 0xfeU))) {
Verilated::overWidthError("clock");}
if (VL_UNLIKELY((reset & 0xfeU))) {
Verilated::overWidthError("reset");}
if (VL_UNLIKELY((io_cin & 0xfeU))) {
Verilated::overWidthError("io_cin");}
}
#endif // VL_DEBUG
void VAdder::_ctor_var_reset() {
VL_DEBUG_IF(VL_DBG_MSGF("+ VAdder::_ctor_var_reset\n"); );
// Body
clock = VL_RAND_RESET_I(1);
reset = VL_RAND_RESET_I(1);
io_a = VL_RAND_RESET_I(8);
io_b = VL_RAND_RESET_I(8);
io_cin = VL_RAND_RESET_I(1);
io_sum = VL_RAND_RESET_I(8);
io_cout = VL_RAND_RESET_I(1);
Adder__DOT___T_io_cout = VL_RAND_RESET_I(1);
Adder__DOT___T_3_io_cout = VL_RAND_RESET_I(1);
Adder__DOT___T_6_io_cout = VL_RAND_RESET_I(1);
Adder__DOT___T_9_io_cout = VL_RAND_RESET_I(1);
Adder__DOT___T_12_io_cout = VL_RAND_RESET_I(1);
Adder__DOT___T_15_io_cout = VL_RAND_RESET_I(1);
Adder__DOT___T_18_io_cout = VL_RAND_RESET_I(1);
__Vm_traceActivity = VL_RAND_RESET_I(32);
}

View File

@ -0,0 +1,106 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Primary design header
//
// This header should be included by all source files instantiating the design.
// The class here is then constructed to instantiate the design.
// See the Verilator manual for examples.
#ifndef _VAdder_H_
#define _VAdder_H_
#include "verilated.h"
class VAdder__Syms;
class VerilatedVcd;
//----------
VL_MODULE(VAdder) {
public:
// PORTS
// The application code writes and reads these signals to
// propagate new values into/out from the Verilated model.
// Begin mtask footprint all:
VL_IN8(clock,0,0);
VL_IN8(reset,0,0);
VL_IN8(io_a,7,0);
VL_IN8(io_b,7,0);
VL_IN8(io_cin,0,0);
VL_OUT8(io_sum,7,0);
VL_OUT8(io_cout,0,0);
// LOCAL SIGNALS
// Internals; generally not touched by application code
// Begin mtask footprint all:
VL_SIG8(Adder__DOT___T_io_cout,0,0);
VL_SIG8(Adder__DOT___T_3_io_cout,0,0);
VL_SIG8(Adder__DOT___T_6_io_cout,0,0);
VL_SIG8(Adder__DOT___T_9_io_cout,0,0);
VL_SIG8(Adder__DOT___T_12_io_cout,0,0);
VL_SIG8(Adder__DOT___T_15_io_cout,0,0);
VL_SIG8(Adder__DOT___T_18_io_cout,0,0);
// LOCAL VARIABLES
// Internals; generally not touched by application code
// Begin mtask footprint all:
VL_SIG(__Vm_traceActivity,31,0);
// INTERNAL VARIABLES
// Internals; generally not touched by application code
VAdder__Syms* __VlSymsp; // Symbol table
// PARAMETERS
// Parameters marked /*verilator public*/ for use by application code
// CONSTRUCTORS
private:
VL_UNCOPYABLE(VAdder); ///< Copying not allowed
public:
/// Construct the model; called by application code
/// The special name may be used to make a wrapper with a
/// single model invisible with respect to DPI scope names.
VAdder(const char* name="TOP");
/// Destroy the model; called (often implicitly) by application code
~VAdder();
/// Trace signals in the model; called by application code
void trace(VerilatedVcdC* tfp, int levels, int options=0);
// API METHODS
/// Evaluate the model. Application must call when inputs change.
void eval();
/// Simulation complete, run final blocks. Application must call on completion.
void final();
// INTERNAL METHODS
private:
static void _eval_initial_loop(VAdder__Syms* __restrict vlSymsp);
public:
void __Vconfigure(VAdder__Syms* symsp, bool first);
private:
static QData _change_request(VAdder__Syms* __restrict vlSymsp);
public:
static void _combo__TOP__1(VAdder__Syms* __restrict vlSymsp);
private:
void _ctor_var_reset() VL_ATTR_COLD;
public:
static void _eval(VAdder__Syms* __restrict vlSymsp);
private:
#ifdef VL_DEBUG
void _eval_debug_assertions();
#endif // VL_DEBUG
public:
static void _eval_initial(VAdder__Syms* __restrict vlSymsp) VL_ATTR_COLD;
static void _eval_settle(VAdder__Syms* __restrict vlSymsp) VL_ATTR_COLD;
static void traceChgThis(VAdder__Syms* __restrict vlSymsp, VerilatedVcd* vcdp, uint32_t code);
static void traceChgThis__2(VAdder__Syms* __restrict vlSymsp, VerilatedVcd* vcdp, uint32_t code);
static void traceFullThis(VAdder__Syms* __restrict vlSymsp, VerilatedVcd* vcdp, uint32_t code) VL_ATTR_COLD;
static void traceFullThis__1(VAdder__Syms* __restrict vlSymsp, VerilatedVcd* vcdp, uint32_t code) VL_ATTR_COLD;
static void traceInitThis(VAdder__Syms* __restrict vlSymsp, VerilatedVcd* vcdp, uint32_t code) VL_ATTR_COLD;
static void traceInitThis__1(VAdder__Syms* __restrict vlSymsp, VerilatedVcd* vcdp, uint32_t code) VL_ATTR_COLD;
static void traceInit(VerilatedVcd* vcdp, void* userthis, uint32_t code);
static void traceFull(VerilatedVcd* vcdp, void* userthis, uint32_t code);
static void traceChg(VerilatedVcd* vcdp, void* userthis, uint32_t code);
} VL_ATTR_ALIGNED(128);
#endif // guard

View File

@ -0,0 +1,66 @@
# Verilated -*- Makefile -*-
# DESCRIPTION: Verilator output: Makefile for building Verilated archive or executable
#
# Execute this makefile from the object directory:
# make -f VAdder.mk
default: VAdder
### Constants...
# Perl executable (from $PERL)
PERL = perl
# Path to Verilator kit (from $VERILATOR_ROOT)
VERILATOR_ROOT = /usr/local/Cellar/verilator/4.020/share/verilator
# SystemC include directory with systemc.h (from $SYSTEMC_INCLUDE)
SYSTEMC_INCLUDE ?=
# SystemC library directory with libsystemc.a (from $SYSTEMC_LIBDIR)
SYSTEMC_LIBDIR ?=
### Switches...
# SystemC output mode? 0/1 (from --sc)
VM_SC = 0
# Legacy or SystemC output mode? 0/1 (from --sc)
VM_SP_OR_SC = $(VM_SC)
# Deprecated
VM_PCLI = 1
# Deprecated: SystemC architecture to find link library path (from $SYSTEMC_ARCH)
VM_SC_TARGET_ARCH = linux
### Vars...
# Design prefix (from --prefix)
VM_PREFIX = VAdder
# Module prefix (from --prefix)
VM_MODPREFIX = VAdder
# User CFLAGS (from -CFLAGS on Verilator command line)
VM_USER_CFLAGS = \
# User LDLIBS (from -LDFLAGS on Verilator command line)
VM_USER_LDLIBS = \
# User .cpp files (from .cpp's on Verilator command line)
VM_USER_CLASSES = \
Adder-harness \
# User .cpp directories (from .cpp's on Verilator command line)
VM_USER_DIR = \
. \
### Default rules...
# Include list of all generated classes
include VAdder_classes.mk
# Include global rules
include $(VERILATOR_ROOT)/include/verilated.mk
### Executable rules... (from --exe)
VPATH += $(VM_USER_DIR)
Adder-harness.o: Adder-harness.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
### Link rules... (from --exe)
VAdder: $(VK_USER_OBJS) $(VK_GLOBAL_OBJS) $(VM_PREFIX)__ALL.a
$(LINK) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) $(SC_LIBS)
# Verilated -*- Makefile -*-

Binary file not shown.

View File

@ -0,0 +1,3 @@
// DESCRIPTION: Generated by verilator_includer via makefile
#define VL_INCLUDE_OPT include
#include "VAdder.cpp"

View File

@ -0,0 +1,4 @@
VAdder__ALLcls.o: VAdder__ALLcls.cpp VAdder.cpp VAdder.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilatedos.h \
VAdder__Syms.h

Binary file not shown.

View File

@ -0,0 +1,5 @@
// DESCRIPTION: Generated by verilator_includer via makefile
#define VL_INCLUDE_OPT include
#include "VAdder__Trace.cpp"
#include "VAdder__Syms.cpp"
#include "VAdder__Trace__Slow.cpp"

View File

@ -0,0 +1,5 @@
VAdder__ALLsup.o: VAdder__ALLsup.cpp VAdder__Trace.cpp \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated_vcd_c.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilatedos.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated.h \
VAdder__Syms.h VAdder.h VAdder__Syms.cpp VAdder__Trace__Slow.cpp

Binary file not shown.

View File

@ -0,0 +1,22 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Symbol table implementation internals
#include "VAdder__Syms.h"
#include "VAdder.h"
// FUNCTIONS
VAdder__Syms::VAdder__Syms(VAdder* topp, const char* namep)
// Setup locals
: __Vm_namep(namep)
, __Vm_activity(false)
, __Vm_didInit(false)
// Setup submodule names
{
// Pointer to top level
TOPp = topp;
// Setup each module's pointers to their submodules
// Setup each module's pointer back to symbol table (for public functions)
TOPp->__Vconfigure(this, true);
}

View File

@ -0,0 +1,37 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Symbol table internal header
//
// Internal details; most calling programs do not need this header,
// unless using verilator public meta comments.
#ifndef _VAdder__Syms_H_
#define _VAdder__Syms_H_
#include "verilated.h"
// INCLUDE MODULE CLASSES
#include "VAdder.h"
// SYMS CLASS
class VAdder__Syms : public VerilatedSyms {
public:
// LOCAL STATE
const char* __Vm_namep;
bool __Vm_activity; ///< Used by trace routines to determine change occurred
bool __Vm_didInit;
// SUBCELL STATE
VAdder* TOPp;
// CREATORS
VAdder__Syms(VAdder* topp, const char* namep);
~VAdder__Syms() {}
// METHODS
inline const char* name() { return __Vm_namep; }
inline bool getClearActivity() { bool r=__Vm_activity; __Vm_activity=false; return r; }
} VL_ATTR_ALIGNED(64);
#endif // guard

View File

@ -0,0 +1,71 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Tracing implementation internals
#include "verilated_vcd_c.h"
#include "VAdder__Syms.h"
//======================
void VAdder::traceChg(VerilatedVcd* vcdp, void* userthis, uint32_t code) {
// Callback from vcd->dump()
VAdder* t = (VAdder*)userthis;
VAdder__Syms* __restrict vlSymsp = t->__VlSymsp; // Setup global symbol table
if (vlSymsp->getClearActivity()) {
t->traceChgThis(vlSymsp, vcdp, code);
}
}
//======================
void VAdder::traceChgThis(VAdder__Syms* __restrict vlSymsp, VerilatedVcd* vcdp, uint32_t code) {
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
int c=code;
if (0 && vcdp && c) {} // Prevent unused
// Body
{
vlTOPp->traceChgThis__2(vlSymsp, vcdp, code);
}
// Final
vlTOPp->__Vm_traceActivity = 0U;
}
void VAdder::traceChgThis__2(VAdder__Syms* __restrict vlSymsp, VerilatedVcd* vcdp, uint32_t code) {
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
int c=code;
if (0 && vcdp && c) {} // Prevent unused
// Body
{
vcdp->chgBit(c+1,(vlTOPp->clock));
vcdp->chgBit(c+2,(vlTOPp->reset));
vcdp->chgBus(c+3,(vlTOPp->io_a),8);
vcdp->chgBus(c+4,(vlTOPp->io_b),8);
vcdp->chgBit(c+5,(vlTOPp->io_cin));
vcdp->chgBus(c+6,(vlTOPp->io_sum),8);
vcdp->chgBit(c+7,(vlTOPp->io_cout));
vcdp->chgBit(c+8,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 7U) ^ (IData)(vlTOPp->Adder__DOT___T_18_io_cout)))));
vcdp->chgBit(c+9,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 6U) ^ (IData)(vlTOPp->Adder__DOT___T_15_io_cout)))));
vcdp->chgBit(c+10,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 5U) ^ (IData)(vlTOPp->Adder__DOT___T_12_io_cout)))));
vcdp->chgBit(c+11,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 4U) ^ (IData)(vlTOPp->Adder__DOT___T_9_io_cout)))));
vcdp->chgBit(c+12,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 3U) ^ (IData)(vlTOPp->Adder__DOT___T_6_io_cout)))));
vcdp->chgBit(c+13,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 2U) ^ (IData)(vlTOPp->Adder__DOT___T_3_io_cout)))));
vcdp->chgBit(c+14,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 1U) ^ (IData)(vlTOPp->Adder__DOT___T_io_cout)))));
vcdp->chgBit(c+15,((1U & (((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
^ (IData)(vlTOPp->io_cin)))));
}
}

View File

@ -0,0 +1,247 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Tracing implementation internals
#include "verilated_vcd_c.h"
#include "VAdder__Syms.h"
//======================
void VAdder::trace(VerilatedVcdC* tfp, int, int) {
tfp->spTrace()->addCallback(&VAdder::traceInit, &VAdder::traceFull, &VAdder::traceChg, this);
}
void VAdder::traceInit(VerilatedVcd* vcdp, void* userthis, uint32_t code) {
// Callback from vcd->open()
VAdder* t = (VAdder*)userthis;
VAdder__Syms* __restrict vlSymsp = t->__VlSymsp; // Setup global symbol table
if (!Verilated::calcUnusedSigs()) {
VL_FATAL_MT(__FILE__,__LINE__,__FILE__,"Turning on wave traces requires Verilated::traceEverOn(true) call before time 0.");
}
vcdp->scopeEscape(' ');
t->traceInitThis(vlSymsp, vcdp, code);
vcdp->scopeEscape('.');
}
void VAdder::traceFull(VerilatedVcd* vcdp, void* userthis, uint32_t code) {
// Callback from vcd->dump()
VAdder* t = (VAdder*)userthis;
VAdder__Syms* __restrict vlSymsp = t->__VlSymsp; // Setup global symbol table
t->traceFullThis(vlSymsp, vcdp, code);
}
//======================
void VAdder::traceInitThis(VAdder__Syms* __restrict vlSymsp, VerilatedVcd* vcdp, uint32_t code) {
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
int c=code;
if (0 && vcdp && c) {} // Prevent unused
vcdp->module(vlSymsp->name()); // Setup signal names
// Body
{
vlTOPp->traceInitThis__1(vlSymsp, vcdp, code);
}
}
void VAdder::traceFullThis(VAdder__Syms* __restrict vlSymsp, VerilatedVcd* vcdp, uint32_t code) {
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
int c=code;
if (0 && vcdp && c) {} // Prevent unused
// Body
{
vlTOPp->traceFullThis__1(vlSymsp, vcdp, code);
}
// Final
vlTOPp->__Vm_traceActivity = 0U;
}
void VAdder::traceInitThis__1(VAdder__Syms* __restrict vlSymsp, VerilatedVcd* vcdp, uint32_t code) {
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
int c=code;
if (0 && vcdp && c) {} // Prevent unused
// Body
{
vcdp->declBit(c+1,"clock",-1);
vcdp->declBit(c+2,"reset",-1);
vcdp->declBus(c+3,"io_a",-1,7,0);
vcdp->declBus(c+4,"io_b",-1,7,0);
vcdp->declBit(c+5,"io_cin",-1);
vcdp->declBus(c+6,"io_sum",-1,7,0);
vcdp->declBit(c+7,"io_cout",-1);
vcdp->declBit(c+1,"Adder clock",-1);
vcdp->declBit(c+2,"Adder reset",-1);
vcdp->declBus(c+3,"Adder io_a",-1,7,0);
vcdp->declBus(c+4,"Adder io_b",-1,7,0);
vcdp->declBit(c+5,"Adder io_cin",-1);
vcdp->declBus(c+6,"Adder io_sum",-1,7,0);
vcdp->declBit(c+7,"Adder io_cout",-1);
// Tracing: Adder _T_io_a // Ignored: Inlined leading underscore at Adder.v:30
// Tracing: Adder _T_io_b // Ignored: Inlined leading underscore at Adder.v:31
// Tracing: Adder _T_io_cin // Ignored: Inlined leading underscore at Adder.v:32
// Tracing: Adder _T_io_sum // Ignored: Inlined leading underscore at Adder.v:33
// Tracing: Adder _T_io_cout // Ignored: Inlined leading underscore at Adder.v:34
// Tracing: Adder _T_3_io_a // Ignored: Inlined leading underscore at Adder.v:35
// Tracing: Adder _T_3_io_b // Ignored: Inlined leading underscore at Adder.v:36
// Tracing: Adder _T_3_io_cin // Ignored: Inlined leading underscore at Adder.v:37
// Tracing: Adder _T_3_io_sum // Ignored: Inlined leading underscore at Adder.v:38
// Tracing: Adder _T_3_io_cout // Ignored: Inlined leading underscore at Adder.v:39
// Tracing: Adder _T_6_io_a // Ignored: Inlined leading underscore at Adder.v:40
// Tracing: Adder _T_6_io_b // Ignored: Inlined leading underscore at Adder.v:41
// Tracing: Adder _T_6_io_cin // Ignored: Inlined leading underscore at Adder.v:42
// Tracing: Adder _T_6_io_sum // Ignored: Inlined leading underscore at Adder.v:43
// Tracing: Adder _T_6_io_cout // Ignored: Inlined leading underscore at Adder.v:44
// Tracing: Adder _T_9_io_a // Ignored: Inlined leading underscore at Adder.v:45
// Tracing: Adder _T_9_io_b // Ignored: Inlined leading underscore at Adder.v:46
// Tracing: Adder _T_9_io_cin // Ignored: Inlined leading underscore at Adder.v:47
// Tracing: Adder _T_9_io_sum // Ignored: Inlined leading underscore at Adder.v:48
// Tracing: Adder _T_9_io_cout // Ignored: Inlined leading underscore at Adder.v:49
// Tracing: Adder _T_12_io_a // Ignored: Inlined leading underscore at Adder.v:50
// Tracing: Adder _T_12_io_b // Ignored: Inlined leading underscore at Adder.v:51
// Tracing: Adder _T_12_io_cin // Ignored: Inlined leading underscore at Adder.v:52
// Tracing: Adder _T_12_io_sum // Ignored: Inlined leading underscore at Adder.v:53
// Tracing: Adder _T_12_io_cout // Ignored: Inlined leading underscore at Adder.v:54
// Tracing: Adder _T_15_io_a // Ignored: Inlined leading underscore at Adder.v:55
// Tracing: Adder _T_15_io_b // Ignored: Inlined leading underscore at Adder.v:56
// Tracing: Adder _T_15_io_cin // Ignored: Inlined leading underscore at Adder.v:57
// Tracing: Adder _T_15_io_sum // Ignored: Inlined leading underscore at Adder.v:58
// Tracing: Adder _T_15_io_cout // Ignored: Inlined leading underscore at Adder.v:59
// Tracing: Adder _T_18_io_a // Ignored: Inlined leading underscore at Adder.v:60
// Tracing: Adder _T_18_io_b // Ignored: Inlined leading underscore at Adder.v:61
// Tracing: Adder _T_18_io_cin // Ignored: Inlined leading underscore at Adder.v:62
// Tracing: Adder _T_18_io_sum // Ignored: Inlined leading underscore at Adder.v:63
// Tracing: Adder _T_18_io_cout // Ignored: Inlined leading underscore at Adder.v:64
// Tracing: Adder _T_21_io_a // Ignored: Inlined leading underscore at Adder.v:65
// Tracing: Adder _T_21_io_b // Ignored: Inlined leading underscore at Adder.v:66
// Tracing: Adder _T_21_io_cin // Ignored: Inlined leading underscore at Adder.v:67
// Tracing: Adder _T_21_io_sum // Ignored: Inlined leading underscore at Adder.v:68
// Tracing: Adder _T_21_io_cout // Ignored: Inlined leading underscore at Adder.v:69
vcdp->declBit(c+8,"Adder sum_7",-1);
vcdp->declBit(c+9,"Adder sum_6",-1);
vcdp->declBit(c+10,"Adder sum_5",-1);
vcdp->declBit(c+11,"Adder sum_4",-1);
// Tracing: Adder _T_26 // Ignored: Inlined leading underscore at Adder.v:74
vcdp->declBit(c+12,"Adder sum_3",-1);
vcdp->declBit(c+13,"Adder sum_2",-1);
vcdp->declBit(c+14,"Adder sum_1",-1);
vcdp->declBit(c+15,"Adder sum_0",-1);
// Tracing: Adder _T_29 // Ignored: Inlined leading underscore at Adder.v:79
// Tracing: Adder _T io_a // Ignored: Inlined leading underscore at Adder.v:2
// Tracing: Adder _T io_b // Ignored: Inlined leading underscore at Adder.v:3
// Tracing: Adder _T io_cin // Ignored: Inlined leading underscore at Adder.v:4
// Tracing: Adder _T io_sum // Ignored: Inlined leading underscore at Adder.v:5
// Tracing: Adder _T io_cout // Ignored: Inlined leading underscore at Adder.v:6
// Tracing: Adder _T a_xor_b // Ignored: Inlined leading underscore at Adder.v:8
// Tracing: Adder _T a_and_b // Ignored: Inlined leading underscore at Adder.v:9
// Tracing: Adder _T b_and_cin // Ignored: Inlined leading underscore at Adder.v:10
// Tracing: Adder _T _T_1 // Ignored: Inlined leading underscore at Adder.v:11
// Tracing: Adder _T a_and_cin // Ignored: Inlined leading underscore at Adder.v:12
// Tracing: Adder _T_3 io_a // Ignored: Inlined leading underscore at Adder.v:2
// Tracing: Adder _T_3 io_b // Ignored: Inlined leading underscore at Adder.v:3
// Tracing: Adder _T_3 io_cin // Ignored: Inlined leading underscore at Adder.v:4
// Tracing: Adder _T_3 io_sum // Ignored: Inlined leading underscore at Adder.v:5
// Tracing: Adder _T_3 io_cout // Ignored: Inlined leading underscore at Adder.v:6
// Tracing: Adder _T_3 a_xor_b // Ignored: Inlined leading underscore at Adder.v:8
// Tracing: Adder _T_3 a_and_b // Ignored: Inlined leading underscore at Adder.v:9
// Tracing: Adder _T_3 b_and_cin // Ignored: Inlined leading underscore at Adder.v:10
// Tracing: Adder _T_3 _T_1 // Ignored: Inlined leading underscore at Adder.v:11
// Tracing: Adder _T_3 a_and_cin // Ignored: Inlined leading underscore at Adder.v:12
// Tracing: Adder _T_6 io_a // Ignored: Inlined leading underscore at Adder.v:2
// Tracing: Adder _T_6 io_b // Ignored: Inlined leading underscore at Adder.v:3
// Tracing: Adder _T_6 io_cin // Ignored: Inlined leading underscore at Adder.v:4
// Tracing: Adder _T_6 io_sum // Ignored: Inlined leading underscore at Adder.v:5
// Tracing: Adder _T_6 io_cout // Ignored: Inlined leading underscore at Adder.v:6
// Tracing: Adder _T_6 a_xor_b // Ignored: Inlined leading underscore at Adder.v:8
// Tracing: Adder _T_6 a_and_b // Ignored: Inlined leading underscore at Adder.v:9
// Tracing: Adder _T_6 b_and_cin // Ignored: Inlined leading underscore at Adder.v:10
// Tracing: Adder _T_6 _T_1 // Ignored: Inlined leading underscore at Adder.v:11
// Tracing: Adder _T_6 a_and_cin // Ignored: Inlined leading underscore at Adder.v:12
// Tracing: Adder _T_9 io_a // Ignored: Inlined leading underscore at Adder.v:2
// Tracing: Adder _T_9 io_b // Ignored: Inlined leading underscore at Adder.v:3
// Tracing: Adder _T_9 io_cin // Ignored: Inlined leading underscore at Adder.v:4
// Tracing: Adder _T_9 io_sum // Ignored: Inlined leading underscore at Adder.v:5
// Tracing: Adder _T_9 io_cout // Ignored: Inlined leading underscore at Adder.v:6
// Tracing: Adder _T_9 a_xor_b // Ignored: Inlined leading underscore at Adder.v:8
// Tracing: Adder _T_9 a_and_b // Ignored: Inlined leading underscore at Adder.v:9
// Tracing: Adder _T_9 b_and_cin // Ignored: Inlined leading underscore at Adder.v:10
// Tracing: Adder _T_9 _T_1 // Ignored: Inlined leading underscore at Adder.v:11
// Tracing: Adder _T_9 a_and_cin // Ignored: Inlined leading underscore at Adder.v:12
// Tracing: Adder _T_12 io_a // Ignored: Inlined leading underscore at Adder.v:2
// Tracing: Adder _T_12 io_b // Ignored: Inlined leading underscore at Adder.v:3
// Tracing: Adder _T_12 io_cin // Ignored: Inlined leading underscore at Adder.v:4
// Tracing: Adder _T_12 io_sum // Ignored: Inlined leading underscore at Adder.v:5
// Tracing: Adder _T_12 io_cout // Ignored: Inlined leading underscore at Adder.v:6
// Tracing: Adder _T_12 a_xor_b // Ignored: Inlined leading underscore at Adder.v:8
// Tracing: Adder _T_12 a_and_b // Ignored: Inlined leading underscore at Adder.v:9
// Tracing: Adder _T_12 b_and_cin // Ignored: Inlined leading underscore at Adder.v:10
// Tracing: Adder _T_12 _T_1 // Ignored: Inlined leading underscore at Adder.v:11
// Tracing: Adder _T_12 a_and_cin // Ignored: Inlined leading underscore at Adder.v:12
// Tracing: Adder _T_15 io_a // Ignored: Inlined leading underscore at Adder.v:2
// Tracing: Adder _T_15 io_b // Ignored: Inlined leading underscore at Adder.v:3
// Tracing: Adder _T_15 io_cin // Ignored: Inlined leading underscore at Adder.v:4
// Tracing: Adder _T_15 io_sum // Ignored: Inlined leading underscore at Adder.v:5
// Tracing: Adder _T_15 io_cout // Ignored: Inlined leading underscore at Adder.v:6
// Tracing: Adder _T_15 a_xor_b // Ignored: Inlined leading underscore at Adder.v:8
// Tracing: Adder _T_15 a_and_b // Ignored: Inlined leading underscore at Adder.v:9
// Tracing: Adder _T_15 b_and_cin // Ignored: Inlined leading underscore at Adder.v:10
// Tracing: Adder _T_15 _T_1 // Ignored: Inlined leading underscore at Adder.v:11
// Tracing: Adder _T_15 a_and_cin // Ignored: Inlined leading underscore at Adder.v:12
// Tracing: Adder _T_18 io_a // Ignored: Inlined leading underscore at Adder.v:2
// Tracing: Adder _T_18 io_b // Ignored: Inlined leading underscore at Adder.v:3
// Tracing: Adder _T_18 io_cin // Ignored: Inlined leading underscore at Adder.v:4
// Tracing: Adder _T_18 io_sum // Ignored: Inlined leading underscore at Adder.v:5
// Tracing: Adder _T_18 io_cout // Ignored: Inlined leading underscore at Adder.v:6
// Tracing: Adder _T_18 a_xor_b // Ignored: Inlined leading underscore at Adder.v:8
// Tracing: Adder _T_18 a_and_b // Ignored: Inlined leading underscore at Adder.v:9
// Tracing: Adder _T_18 b_and_cin // Ignored: Inlined leading underscore at Adder.v:10
// Tracing: Adder _T_18 _T_1 // Ignored: Inlined leading underscore at Adder.v:11
// Tracing: Adder _T_18 a_and_cin // Ignored: Inlined leading underscore at Adder.v:12
// Tracing: Adder _T_21 io_a // Ignored: Inlined leading underscore at Adder.v:2
// Tracing: Adder _T_21 io_b // Ignored: Inlined leading underscore at Adder.v:3
// Tracing: Adder _T_21 io_cin // Ignored: Inlined leading underscore at Adder.v:4
// Tracing: Adder _T_21 io_sum // Ignored: Inlined leading underscore at Adder.v:5
// Tracing: Adder _T_21 io_cout // Ignored: Inlined leading underscore at Adder.v:6
// Tracing: Adder _T_21 a_xor_b // Ignored: Inlined leading underscore at Adder.v:8
// Tracing: Adder _T_21 a_and_b // Ignored: Inlined leading underscore at Adder.v:9
// Tracing: Adder _T_21 b_and_cin // Ignored: Inlined leading underscore at Adder.v:10
// Tracing: Adder _T_21 _T_1 // Ignored: Inlined leading underscore at Adder.v:11
// Tracing: Adder _T_21 a_and_cin // Ignored: Inlined leading underscore at Adder.v:12
}
}
void VAdder::traceFullThis__1(VAdder__Syms* __restrict vlSymsp, VerilatedVcd* vcdp, uint32_t code) {
VAdder* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;
int c=code;
if (0 && vcdp && c) {} // Prevent unused
// Body
{
vcdp->fullBit(c+1,(vlTOPp->clock));
vcdp->fullBit(c+2,(vlTOPp->reset));
vcdp->fullBus(c+3,(vlTOPp->io_a),8);
vcdp->fullBus(c+4,(vlTOPp->io_b),8);
vcdp->fullBit(c+5,(vlTOPp->io_cin));
vcdp->fullBus(c+6,(vlTOPp->io_sum),8);
vcdp->fullBit(c+7,(vlTOPp->io_cout));
vcdp->fullBit(c+8,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 7U) ^ (IData)(vlTOPp->Adder__DOT___T_18_io_cout)))));
vcdp->fullBit(c+9,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 6U) ^ (IData)(vlTOPp->Adder__DOT___T_15_io_cout)))));
vcdp->fullBit(c+10,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 5U) ^ (IData)(vlTOPp->Adder__DOT___T_12_io_cout)))));
vcdp->fullBit(c+11,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 4U) ^ (IData)(vlTOPp->Adder__DOT___T_9_io_cout)))));
vcdp->fullBit(c+12,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 3U) ^ (IData)(vlTOPp->Adder__DOT___T_6_io_cout)))));
vcdp->fullBit(c+13,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 2U) ^ (IData)(vlTOPp->Adder__DOT___T_3_io_cout)))));
vcdp->fullBit(c+14,((1U & ((((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
>> 1U) ^ (IData)(vlTOPp->Adder__DOT___T_io_cout)))));
vcdp->fullBit(c+15,((1U & (((IData)(vlTOPp->io_a)
^ (IData)(vlTOPp->io_b))
^ (IData)(vlTOPp->io_cin)))));
}
}

View File

@ -0,0 +1 @@
obj_dir/VAdder.cpp obj_dir/VAdder.h obj_dir/VAdder.mk obj_dir/VAdder__Syms.cpp obj_dir/VAdder__Syms.h obj_dir/VAdder__Trace.cpp obj_dir/VAdder__Trace__Slow.cpp obj_dir/VAdder__ver.d obj_dir/VAdder_classes.mk : /usr/local/Cellar/verilator/4.020/bin/verilator_bin /usr/local/Cellar/verilator/4.020/bin/verilator_bin Adder.v

View File

@ -0,0 +1,14 @@
# DESCRIPTION: Verilator output: Timestamp data for --skip-identical. Delete at will.
C "--cc Adder.v --trace --exe Adder-harness.cpp"
S 4592620 6135827 1585561266 0 1570370593 0 "/usr/local/Cellar/verilator/4.020/bin/verilator_bin"
S 3979 7788080 1586844837 0 1586844837 0 "Adder.v"
T 14142 7788088 1586844837 0 1586844837 0 "obj_dir/VAdder.cpp"
T 3956 7788087 1586844837 0 1586844837 0 "obj_dir/VAdder.h"
T 1803 7788090 1586844837 0 1586844837 0 "obj_dir/VAdder.mk"
T 566 7788083 1586844837 0 1586844837 0 "obj_dir/VAdder__Syms.cpp"
T 928 7788084 1586844837 0 1586844837 0 "obj_dir/VAdder__Syms.h"
T 3096 7788086 1586844837 0 1586844837 0 "obj_dir/VAdder__Trace.cpp"
T 16400 7788085 1586844837 0 1586844837 0 "obj_dir/VAdder__Trace__Slow.cpp"
T 324 7788091 1586844837 0 1586844837 0 "obj_dir/VAdder__ver.d"
T 0 0 1586844837 0 1586844837 0 "obj_dir/VAdder__verFiles.dat"
T 1301 7788089 1586844837 0 1586844837 0 "obj_dir/VAdder_classes.mk"

View File

@ -0,0 +1,43 @@
# Verilated -*- Makefile -*-
# DESCRIPTION: Verilator output: Make include file with class lists
#
# This file lists generated Verilated files, for including in higher level makefiles.
# See VAdder.mk for the caller.
### Switches...
# Coverage output mode? 0/1 (from --coverage)
VM_COVERAGE = 0
# Threaded output mode? 0/1/N threads (from --threads)
VM_THREADS = 0
# Tracing output mode? 0/1 (from --trace)
VM_TRACE = 1
# Tracing threadeds output mode? 0/1 (from --trace-fst-thread)
VM_TRACE_THREADED = 0
### Object file lists...
# Generated module classes, fast-path, compile with highest optimization
VM_CLASSES_FAST += \
VAdder \
# Generated module classes, non-fast-path, compile with low/medium optimization
VM_CLASSES_SLOW += \
# Generated support classes, fast-path, compile with highest optimization
VM_SUPPORT_FAST += \
VAdder__Trace \
# Generated support classes, non-fast-path, compile with low/medium optimization
VM_SUPPORT_SLOW += \
VAdder__Syms \
VAdder__Trace__Slow \
# Global classes, need linked once per executable, fast-path, compile with highest optimization
VM_GLOBAL_FAST += \
verilated \
verilated_vcd_c \
# Global classes, need linked once per executable, non-fast-path, compile with low/medium optimization
VM_GLOBAL_SLOW += \
# Verilated -*- Makefile -*-

View File

@ -0,0 +1,9 @@
verilated.o: \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated.cpp \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilatedos.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated_imp.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated_heavy.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated_syms.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated_sym_props.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated_config.h

Binary file not shown.

View File

@ -0,0 +1,5 @@
verilated_vcd_c.o: \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated_vcd_c.cpp \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilatedos.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated.h \
/usr/local/Cellar/verilator/4.020/share/verilator/include/verilated_vcd_c.h

Binary file not shown.

View File

@ -0,0 +1,221 @@
#include <verilated.h>
#include <verilated_vcd_c.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <vector>
#include <map>
using namespace std;
// Signals value
#define WAIT 0
#define DOUT 1
#define DIN 2
#define TERM 3
#define STEP 4
#define START 5
#define RESET 6
/* Simulation finish flag */
size_t is_exit = 0;
class DataWrapper
{
public:
virtual void poke(uint64_t value) = 0;
virtual uint64_t peek() = 0;
};
// Wrap Verilator data types
class CDataWrapper: public DataWrapper
{
private:
CData *signal;
public:
CDataWrapper(CData *_signal)
{
this->signal = _signal;
}
virtual void poke(uint64_t value)
{
uint64_t mask = 0xff;
*signal = (CData) (mask & value);
}
virtual uint64_t peek()
{
return (uint64_t) *signal;
}
};
class SDataWrapper: public DataWrapper
{
private:
SData *signal;
public:
SDataWrapper(SData *_signal)
{
this->signal = _signal;
}
virtual void poke(uint64_t value)
{
uint64_t mask = 0xffff;
*signal = (SData) (mask & value);
}
virtual uint64_t peek()
{
return (uint64_t) *signal;
}
};
class IDataWrapper: public DataWrapper
{
private:
IData *signal;
public:
IDataWrapper(IData *_signal)
{
this->signal = _signal;
}
virtual void poke(uint64_t value)
{
uint64_t mask = 0xffffffff;
*signal = (IData) (mask & value);
}
virtual uint64_t peek()
{
return (uint64_t) *signal;
}
};
class QDataWrapper: public DataWrapper
{
private:
QData *signal;
public:
QDataWrapper(QData *_signal)
{
this->signal = _signal;
}
virtual void poke(uint64_t value)
{
*signal = (QData) value;
}
virtual uint64_t peek()
{
return (uint64_t) *signal;
}
};
template<class T> struct Sim_data
{
vector<T> inputs;
vector<T> outputs;
};
template<class T> class Simulator
{
protected:
uint64_t *in;
uint64_t *out;
uint64_t *sig;
Sim_data<T> sim_datas;
uint64_t main_time;
int in_fd;
int out_fd;
int sig_fd;
public:
Simulator()
{
// Create file memory mapping
this->in_fd = open("in.dat", O_RDWR | O_CREAT, 00777);
this->out_fd = open("out.dat", O_RDWR | O_CREAT, 00777);
this->sig_fd = open("sig.dat", O_RDWR | O_CREAT, 00777);
int psize = getpagesize();
ftruncate(this->in_fd, psize);
ftruncate(this->out_fd, psize);
ftruncate(this->sig_fd, psize);
this->in = (uint64_t*)mmap(NULL, psize, PROT_WRITE | PROT_READ, MAP_SHARED, this->in_fd, 0);
this->out = (uint64_t*)mmap(NULL, psize, PROT_WRITE | PROT_READ, MAP_SHARED, this->out_fd, 0);
this->sig = (uint64_t*)mmap(NULL, psize, PROT_WRITE | PROT_READ, MAP_SHARED, this->sig_fd, 0);
if (this->in == MAP_FAILED || this->out == MAP_FAILED || this->sig == MAP_FAILED)
{
perror("mmap failed");
exit(1);
}
*(this->sig) = WAIT; // Initial signal
this->main_time = 0;
}
virtual void input_value(uint64_t *in)
{
int signal_num = (int)in[1];
T obj = this->sim_datas.inputs[signal_num];
obj->poke(in[0]);
}
virtual void output_value(uint64_t *out)
{
int signal_num = (int)out[1];
T obj = this->sim_datas.outputs[signal_num];
uint64_t wdata = obj->peek();
out[0] = wdata;
}
virtual void step() = 0;
virtual void reset() = 0;
virtual void start() = 0;
virtual void finish()
{
is_exit = 1;
}
bool isexit()
{
return is_exit;
}
void tick()
{
/* Signal ticks, deal with every incomming signal */
// Waiting for signal
while(1)
{
while (*sig == WAIT);
switch (*sig)
{
case DIN: input_value(this->in); break;
case DOUT: output_value(this->out); break;
case STEP: step(); break;
case RESET: reset(); break;
case TERM: finish(); break;
case START: start(); break;
default: break;
}
if (is_exit)
break;
// Wait for next signal
*sig = WAIT;
}
}
};

32
example/test.py Normal file
View File

@ -0,0 +1,32 @@
from functools import reduce
from pyhcl import *
class Test(Module):
io = IO(
DIO_stop=Output(U.w(1)),
Jotaro_stop=Output(U.w(1))
)
counter = RegInit(U.w(32)(0))
DIO_stop_r = RegInit(U.w(1)(1))
Jotaro_stop_r = RegInit(U.w(1)(0))
counter <<= counter + U(1)
with when(counter == U(10)):
io.DIO_stop <<= U(0)
DIO_stop_r <<= U(0)
with otherwise():
io.DIO_stop <<= DIO_stop_r
with when(io.DIO_stop == U(0)):
io.Jotaro_stop <<= U(1)
Jotaro_stop_r <<= U(1)
with otherwise():
io.Jotaro_stop <<= Jotaro_stop_r
if __name__ == '__main__':
Emitter.dumpVerilog(Emitter.dump(Emitter.emit(Test()), "test.fir"))

20
main.py Normal file
View File

@ -0,0 +1,20 @@
if __name__ == '__main__':
input = [2, -6]
ws1 = [[0.17, 1.2], [-0.97, 1.1], [-0.77, -0.16], [-0.94, -0.19]]
output1 = [input[0] * w[0] + input[1] * w[1] for w in ws1]
# input2 = [i if i > 0 else 0 for i in output1]
input2 = output1
ws2 = [[1.1, -0.3, 0.79, .66], [-.76, 1.5, -.25, -.73]]
output2 = [input2[0] * w[0] + input2[1] * w[1] + input2[2] * w[2] + input2[3] * w[3] for w in ws2]
input3 = [i if i > 0 else 0 for i in output2]
ws3 = [1.4, -2.0]
output3 = ws3[0] * input3[0] + ws3[1] * input3[1]
print(output2)
# print((sum(a * b for a, b in zip([1.2, 1.1, -0.16, -0.19], [x2 for _ in range(4)]))))

View File

@ -1,2 +0,0 @@
from .dsl import * # noqa: F403, F401
from .compile import compile_to_firrtl # noqa: F401

View File

@ -1,11 +0,0 @@
from py_hcl.transformer.pyhcl_to_firrtl.convertor import convert
def compile_to_firrtl(module_class, path=None):
m = convert(module_class.packed_module)
if path is None:
path = module_class.packed_module.name + ".fir"
with open(path, 'wb') as f:
m.serialize_stmt(f)

View File

@ -1,11 +0,0 @@
def install_ops():
import py_hcl.core.expr.add # noqa: F401
import py_hcl.core.expr.and_ # noqa: F401
import py_hcl.core.expr.xor # noqa: F401
import py_hcl.core.expr.or_ # noqa: F401
import py_hcl.core.stmt.connect # noqa: F401
import py_hcl.core.expr.field # noqa: F401
import py_hcl.core.expr.slice # noqa: F401
import py_hcl.core.expr.index # noqa: F401
import py_hcl.core.expr.convert # noqa: F401
import py_hcl.core.expr.extend # noqa: F401

View File

@ -1,5 +0,0 @@
from py_hcl.error import PyHclError
class CoreError(PyHclError):
pass

View File

@ -1,103 +0,0 @@
from multipledispatch.dispatcher import MethodDispatcher
from py_hcl.core.hcl_ops import op_apply
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.core.type import UnknownType, HclType
from py_hcl.utils import json_serialize
class ExprIdGen:
id = -1
@classmethod
def next_id(cls):
cls.id += 1
return cls.id
class ExprTable:
table = {}
@classmethod
def add(cls, i, obj):
cls.table[i] = obj
@classmethod
def get(cls, i):
return cls.table[i]
@json_serialize
class HclExpr(object):
hcl_type = UnknownType()
conn_side = ConnSide.UNKNOWN
def __new__(cls, *args):
obj = super().__new__(cls)
obj.id = ExprIdGen.next_id()
ExprTable.add(obj.id, obj)
return obj
def __ilshift__(self, other):
return op_apply('<<=')(self, other)
def __add__(self, other):
return op_apply('+')(self, other)
def __and__(self, other):
return op_apply('&')(self, other)
def __or__(self, other):
return op_apply('|')(self, other)
def __xor__(self, other):
return op_apply('^')(self, other)
def __getattr__(self, item):
return op_apply('.')(self, item)
def __setitem__(self, key, value):
return self[key]
__getitem__ = MethodDispatcher('__getitem__')
@__getitem__.register(tuple)
def _(self, item):
if len(item) == 1:
return self[item[0]]
return self.__getitem__(item[0])[item[1:]]
@__getitem__.register(slice)
def _(self, item):
start = item.start if item.start is not None else 0
if item.step is None:
if item.stop is not None:
return op_apply('[i:j]')(self, start, item.stop)
if item.stop is None:
return op_apply('[i:]')(self, start)
if item.stop is not None:
return op_apply('[i:j:k]')(self, start, item.stop, item.step)
if item.stop is None:
return op_apply('[i::k]')(self, start, item.step)
@__getitem__.register(int)
def _(self, item):
return op_apply('[i]')(self, item)
def to_uint(self):
return op_apply('to_uint')(self)
def to_sint(self):
return op_apply('to_sint')(self)
def to_bool(self):
return op_apply('to_bool')(self)
@json_serialize(json_fields=['id', 'type', 'hcl_type', 'conn_side', 'op_node'])
class ExprHolder(HclExpr):
def __init__(self, hcl_type: HclType, conn_side: ConnSide, op_node):
self.type = 'expr_holder'
self.hcl_type = hcl_type
self.conn_side = conn_side
self.op_node = op_node

View File

@ -1,72 +0,0 @@
from py_hcl.core.expr import ExprHolder
from py_hcl.core.expr.bundle_holder import BundleHolder
from py_hcl.core.expr.error import ExprError
from py_hcl.core.expr.utils import assert_right_side
from py_hcl.core.expr.vec_holder import VecHolder
from py_hcl.core.hcl_ops import op_register
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.core.type import HclType
from py_hcl.core.type.bundle import BundleT, Dir
from py_hcl.core.type.sint import SIntT
from py_hcl.core.type.uint import UIntT
from py_hcl.core.type.vector import VectorT
from py_hcl.utils import json_serialize
@json_serialize
class Add(object):
def __init__(self, left, right):
self.operation = 'add'
self.left_expr_id = left.id
self.right_expr_id = right.id
adder = op_register('+')
@adder(UIntT, UIntT)
@assert_right_side
def _(lf, rt):
w = max(lf.hcl_type.width, rt.hcl_type.width) + 1
t = UIntT(w)
return ExprHolder(t, ConnSide.RT, Add(lf, rt))
@adder(SIntT, SIntT)
@assert_right_side
def _(lf, rt):
w = max(lf.hcl_type.width, rt.hcl_type.width) + 1
t = SIntT(w)
return ExprHolder(t, ConnSide.RT, Add(lf, rt))
@adder(VectorT, VectorT)
@assert_right_side
def _(lf, rt):
# TODO: Accurate Error Message
assert lf.hcl_type.size == rt.hcl_type.size
values = [lf[i] + rt[i] for i in range(lf.hcl_type.size)]
v_type = VectorT(values[0].hcl_type, len(values))
return VecHolder(v_type, ConnSide.RT, values)
@adder(BundleT, BundleT)
@assert_right_side
def _(lf, rt):
# TODO: Accurate Error Message
assert set(lf.hcl_type.fields.keys()) == set(rt.hcl_type.fields.keys())
bd_type_fields = {}
bd_values = {}
for k in lf.hcl_type.fields.keys():
res = getattr(lf, k) + getattr(rt, k)
bd_type_fields[k] = {"dir": Dir.SRC, "hcl_type": res.hcl_type}
bd_values[k] = res
return BundleHolder(BundleT(bd_type_fields), ConnSide.RT, bd_values)
@adder(HclType, HclType)
def _(_0, _1):
raise ExprError.op_type_err('add', _0, _1)

View File

@ -1,72 +0,0 @@
from py_hcl.core.expr import ExprHolder
from py_hcl.core.expr.bundle_holder import BundleHolder
from py_hcl.core.expr.error import ExprError
from py_hcl.core.expr.utils import assert_right_side
from py_hcl.core.expr.vec_holder import VecHolder
from py_hcl.core.hcl_ops import op_register
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.core.type import HclType
from py_hcl.core.type.bundle import BundleT, Dir
from py_hcl.core.type.sint import SIntT
from py_hcl.core.type.uint import UIntT
from py_hcl.core.type.vector import VectorT
from py_hcl.utils import json_serialize
@json_serialize
class And(object):
def __init__(self, left, right):
self.operation = 'and'
self.left_expr_id = left.id
self.right_expr_id = right.id
ander = op_register('&')
@ander(UIntT, UIntT)
@assert_right_side
def _(lf, rt):
w = max(lf.hcl_type.width, rt.hcl_type.width)
t = UIntT(w)
return ExprHolder(t, ConnSide.RT, And(lf, rt))
@ander(SIntT, SIntT)
@assert_right_side
def _(lf, rt):
w = max(lf.hcl_type.width, rt.hcl_type.width)
t = UIntT(w)
return ExprHolder(t, ConnSide.RT, And(lf, rt))
@ander(VectorT, VectorT)
@assert_right_side
def _(lf, rt):
# TODO: Accurate Error Message
assert lf.hcl_type.size == rt.hcl_type.size
values = [lf[i] & rt[i] for i in range(lf.hcl_type.size)]
v_type = VectorT(values[0].hcl_type, len(values))
return VecHolder(v_type, ConnSide.RT, values)
@ander(BundleT, BundleT)
@assert_right_side
def _(lf, rt):
# TODO: Accurate Error Message
assert set(lf.hcl_type.fields.keys()) == set(rt.hcl_type.fields.keys())
bd_type_fields = {}
bd_values = {}
for k in lf.hcl_type.fields.keys():
res = getattr(lf, k) & getattr(rt, k)
bd_type_fields[k] = {"dir": Dir.SRC, "hcl_type": res.hcl_type}
bd_values[k] = res
return BundleHolder(BundleT(bd_type_fields), ConnSide.RT, bd_values)
@ander(HclType, HclType)
def _(_0, _1):
raise ExprError.op_type_err('and', _0, _1)

View File

@ -1,12 +0,0 @@
from py_hcl.core.expr import HclExpr
from py_hcl.core.type.bundle import BundleT
class BundleHolder(HclExpr):
def __init__(self, hcl_type, conn_side, assoc_value):
self.hcl_type = hcl_type
self.conn_side = conn_side
assert isinstance(hcl_type, BundleT)
assert set(hcl_type.fields.keys()) == set(assoc_value.keys())
self.assoc_value = assoc_value

View File

@ -1,80 +0,0 @@
from py_hcl.core.expr import ExprHolder
from py_hcl.core.expr.error import ExprError
from py_hcl.core.expr.utils import assert_right_side
from py_hcl.core.hcl_ops import op_register
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.core.type import HclType
from py_hcl.core.type.sint import SIntT
from py_hcl.core.type.uint import UIntT
from py_hcl.utils import json_serialize
to_bool = op_register('to_bool')
to_uint = op_register('to_uint')
to_sint = op_register('to_sint')
@json_serialize
class ToSInt(object):
def __init__(self, expr):
self.operation = "to_sint"
self.ref_expr_id = expr.id
@json_serialize
class ToUInt(object):
def __init__(self, expr):
self.operation = "to_uint"
self.ref_expr_id = expr.id
@to_bool(UIntT)
@assert_right_side
def _(uint):
return uint[0]
@to_bool(SIntT)
@assert_right_side
def _(sint):
return sint[0]
@to_bool(HclType)
def _(_0, *_):
raise ExprError.op_type_err('to_bool', _0)
@to_uint(UIntT)
@assert_right_side
def _(uint):
return uint
@to_uint(SIntT)
@assert_right_side
def _(sint):
t = UIntT(sint.hcl_type.width)
return ExprHolder(t, ConnSide.RT, ToUInt(sint))
@to_uint(HclType)
def _(_0, *_):
raise ExprError.op_type_err('to_uint', _0)
@to_sint(UIntT)
@assert_right_side
def _(uint):
t = SIntT(uint.hcl_type.width)
return ExprHolder(t, ConnSide.RT, ToSInt(uint))
@to_sint(SIntT)
@assert_right_side
def _(sint):
return sint
@to_sint(HclType)
def _(_0, *_):
raise ExprError.op_type_err('to_sint', _0)

View File

@ -1,28 +0,0 @@
from py_hcl.core.error import CoreError
def set_up():
ExprError.append({
'IOValueError': {
'code': 200,
'value': ExprError('io items should wrap with Input or Output')},
'OpTypeError': {
'code': 201,
'value': ExprError('specified arguments contain unexpected types')
}
})
class ExprError(CoreError):
@staticmethod
def io_value(msg):
return ExprError.err('IOValueError', msg)
@staticmethod
def op_type_err(op, *args):
ts = ', '.join([type(a.hcl_type).__name__ for a in args])
msg = '{}(): unsupported operand types: {}'.format(op, ts)
return ExprError.err('OpTypeError', msg)
set_up()

View File

@ -1,28 +0,0 @@
from py_hcl.core.expr import ExprHolder
from py_hcl.core.expr.utils import assert_right_side
from py_hcl.core.hcl_ops import op_register
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.core.type.sint import SIntT
from py_hcl.core.type.uint import UIntT
from py_hcl.utils import json_serialize
extend = op_register('extend')
@json_serialize
class Extend(object):
def __init__(self, expr):
self.operation = 'extend'
self.ref_expr_id = expr.id
@extend(UIntT)
@assert_right_side
def _(uint, size):
return ExprHolder(UIntT(size), ConnSide.RT, Extend(uint))
@extend(SIntT)
@assert_right_side
def _(sint, size):
return ExprHolder(SIntT(size), ConnSide.RT, Extend(sint))

View File

@ -1,49 +0,0 @@
from py_hcl.core.expr import ExprHolder
from py_hcl.core.expr.bundle_holder import BundleHolder
from py_hcl.core.expr.error import ExprError
from py_hcl.core.hcl_ops import op_register
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.core.type import HclType
from py_hcl.core.type.bundle import BundleT, Dir
from py_hcl.utils import json_serialize
field_accessor = op_register('.')
@json_serialize
class FieldAccess(object):
def __init__(self, expr, item):
self.operation = "field_access"
self.item = item
self.ref_expr_id = expr.id
@field_accessor(BundleT)
def _(bd, item):
# TODO: Accurate Error Message
assert item in bd.hcl_type.fields
if isinstance(bd, BundleHolder):
return bd.assoc_value[item]
# build connect side
sd = bd.conn_side
f = bd.hcl_type.fields[item]
dr, tpe = f["dir"], f["hcl_type"]
new_sd = build_new_sd(sd, dr)
return ExprHolder(tpe, new_sd, FieldAccess(bd, item))
@field_accessor(HclType)
def _(o, *_):
raise ExprError.op_type_err('field_accessor', o)
def build_new_sd(sd: ConnSide, dr: Dir) -> ConnSide:
if sd == ConnSide.BOTH:
return ConnSide.BOTH
if sd == ConnSide.RT and dr == dr.SINK:
return ConnSide.LF
if sd == ConnSide.LF and dr == dr.SRC:
return ConnSide.LF
return ConnSide.RT

View File

@ -1,46 +0,0 @@
from py_hcl.core.expr import ExprHolder
from py_hcl.core.expr.error import ExprError
from py_hcl.core.expr.utils import assert_right_side
from py_hcl.core.expr.vec_holder import VecHolder
from py_hcl.core.hcl_ops import op_register
from py_hcl.core.type import HclType
from py_hcl.core.type.sint import SIntT
from py_hcl.core.type.uint import UIntT
from py_hcl.core.type.vector import VectorT
from py_hcl.utils import json_serialize
index = op_register('[i]')
@json_serialize
class VecIndex(object):
def __init__(self, expr, idx: int):
self.operation = "vec_index"
self.index = idx
self.ref_expr_id = expr.id
@index(UIntT)
@assert_right_side
def _(uint, i: int):
return uint[i:i]
@index(SIntT)
@assert_right_side
def _(sint, i: int):
return sint[i:i]
@index(VectorT)
def _(vec, i: int):
# TODO: Accurate Error Message
assert i < vec.hcl_type.size
if isinstance(vec, VecHolder):
return vec.assoc_value[i]
return ExprHolder(vec.hcl_type.inner_type, vec.conn_side, VecIndex(vec, i))
@index(HclType)
def _(_0, *_):
raise ExprError.op_type_err('index', _0)

View File

@ -1,85 +0,0 @@
from typing import Dict, Union, Optional, Tuple
from py_hcl.core.expr import HclExpr
from py_hcl.core.expr.error import ExprError
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.core.type import HclType
from py_hcl.core.type.bundle import Dir, BundleT
from py_hcl.core.utils import module_inherit_mro
from py_hcl.utils import json_serialize
@json_serialize
class Input(object):
def __init__(self, hcl_type: HclType):
self.port_dir = 'input'
self.hcl_type = hcl_type
@json_serialize
class Output(object):
def __init__(self, hcl_type: HclType):
self.port_dir = 'output'
self.hcl_type = hcl_type
@json_serialize
class IOHolder(object):
def __init__(self, named_ports: Dict[str, Union[Input, Output]],
module_name: Optional[str] = None):
self.named_ports = named_ports
self.module_name = module_name
@json_serialize
class IONode(object):
def __init__(self, io_holder: IOHolder,
next_node: Optional["IOHolder"]):
self.io_holder = io_holder
if next_node is not None:
self.next_node = next_node
@json_serialize(json_fields=["id", "type", "hcl_type",
"conn_side", "io_chain_head"])
class IO(HclExpr):
def __init__(self, hcl_type: HclType, io_chain_head: IONode):
self.type = 'io'
self.hcl_type = hcl_type
self.conn_side = ConnSide.RT
self.io_chain_head = io_chain_head
def io_extend(modules: Tuple[type]):
modules = module_inherit_mro(modules)
current_ports = {}
io_chain = None
for m in modules[::-1]:
h = m.io.io_chain_head.io_holder
current_ports.update(h.named_ports)
io_chain = IONode(h, io_chain)
def _(named_ports: Dict[str, Union[Input, Output]]):
current_ports.update(named_ports)
io_chain_head = IONode(IOHolder(named_ports), io_chain)
return IO(calc_type_from_ports(current_ports), io_chain_head)
return _
def calc_type_from_ports(named_ports: Dict[str, Union[Input, Output]]):
types = {}
for k, v in named_ports.items():
if isinstance(v, Input):
types[k] = {"dir": Dir.SRC, "hcl_type": v.hcl_type}
continue
if isinstance(v, Output):
types[k] = {"dir": Dir.SINK, "hcl_type": v.hcl_type}
continue
raise ExprError.io_value(
"type of '{}' is {}, not Input or Output".format(k, type(v)))
return BundleT(types)

View File

@ -1,13 +0,0 @@
from py_hcl.core.expr import HclExpr
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.core.type.sint import SIntT
from py_hcl.utils import signed_num_bin_len
class SLiteral(HclExpr):
def __init__(self, value: int):
self.value = value
w = signed_num_bin_len(value)
self.hcl_type = SIntT(w)
self.conn_side = ConnSide.RT

View File

@ -1,13 +0,0 @@
from py_hcl.core.expr import HclExpr
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.core.type.uint import UIntT
from py_hcl.utils import unsigned_num_bin_len
class ULiteral(HclExpr):
def __init__(self, value: int):
self.value = value
w = unsigned_num_bin_len(value)
self.hcl_type = UIntT(w)
self.conn_side = ConnSide.RT

View File

@ -1,18 +0,0 @@
from py_hcl.core.expr import HclExpr
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.utils import json_serialize
@json_serialize(
json_fields=['id', 'type', 'hcl_type', "conn_side", 'module_name'])
class ModuleInst(HclExpr):
def __init__(self, module_cls):
self.type = 'module_inst'
self.hcl_type = module_cls.io.hcl_type
self.conn_side = ConnSide.LF
self.packed_module = module_cls.packed_module
self.module_name = module_cls.packed_module.name
def con_module(module_cls):
return ModuleInst(module_cls)

View File

@ -1,72 +0,0 @@
from py_hcl.core.expr import ExprHolder
from py_hcl.core.expr.bundle_holder import BundleHolder
from py_hcl.core.expr.error import ExprError
from py_hcl.core.expr.utils import assert_right_side
from py_hcl.core.expr.vec_holder import VecHolder
from py_hcl.core.hcl_ops import op_register
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.core.type import HclType
from py_hcl.core.type.bundle import BundleT, Dir
from py_hcl.core.type.sint import SIntT
from py_hcl.core.type.uint import UIntT
from py_hcl.core.type.vector import VectorT
from py_hcl.utils import json_serialize
@json_serialize
class Or(object):
def __init__(self, left, right):
self.operation = 'or'
self.left_expr_id = left.id
self.right_expr_id = right.id
orer = op_register('|')
@orer(UIntT, UIntT)
@assert_right_side
def _(lf, rt):
w = max(lf.hcl_type.width, rt.hcl_type.width)
t = UIntT(w)
return ExprHolder(t, ConnSide.RT, Or(lf, rt))
@orer(SIntT, SIntT)
@assert_right_side
def _(lf, rt):
w = max(lf.hcl_type.width, rt.hcl_type.width)
t = UIntT(w)
return ExprHolder(t, ConnSide.RT, Or(lf, rt))
@orer(VectorT, VectorT)
@assert_right_side
def _(lf, rt):
# TODO: Accurate Error Message
assert lf.hcl_type.size == rt.hcl_type.size
values = [lf[i] | rt[i] for i in range(lf.hcl_type.size)]
v_type = VectorT(values[0].hcl_type, len(values))
return VecHolder(v_type, ConnSide.RT, values)
@orer(BundleT, BundleT)
@assert_right_side
def _(lf, rt):
# TODO: Accurate Error Message
assert set(lf.hcl_type.fields.keys()) == set(rt.hcl_type.fields.keys())
bd_type_fields = {}
bd_values = {}
for k in lf.hcl_type.fields.keys():
res = getattr(lf, k) | getattr(rt, k)
bd_type_fields[k] = {"dir": Dir.SRC, "hcl_type": res.hcl_type}
bd_values[k] = res
return BundleHolder(BundleT(bd_type_fields), ConnSide.RT, bd_values)
@orer(HclType, HclType)
def _(_0, _1):
raise ExprError.op_type_err('or', _0, _1)

View File

@ -1,68 +0,0 @@
from py_hcl.core.expr import ExprHolder
from py_hcl.core.expr.error import ExprError
from py_hcl.core.expr.utils import assert_right_side
from py_hcl.core.expr.vec_holder import VecHolder
from py_hcl.core.hcl_ops import op_register
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.core.type import HclType
from py_hcl.core.type.sint import SIntT
from py_hcl.core.type.uint import UIntT
from py_hcl.core.type.vector import VectorT
from py_hcl.utils import json_serialize
slice_ = op_register('[i:j]')
@json_serialize
class Bits(object):
def __init__(self, expr, high, low):
self.operation = 'bits'
self.high = high
self.low = low
self.ref_expr_id = expr.id
@slice_(UIntT)
@assert_right_side
def _(uint, high: int, low: int):
check_bit_width(uint, high, low)
t = UIntT(high - low + 1)
return ExprHolder(t, ConnSide.RT, Bits(uint, high, low))
@slice_(SIntT)
@assert_right_side
def _(sint, high: int, low: int):
check_bit_width(sint, high, low)
t = UIntT(high - low + 1)
return ExprHolder(t, ConnSide.RT, Bits(sint, high, low))
@slice_(VectorT)
def _(vec, low: int, high: int):
check_vec_size(vec, low, high)
if isinstance(vec, VecHolder):
values = vec.assoc_value[low: high]
else:
values = [vec[i] for i in range(low, high, 1)]
v_type = VectorT(vec.hcl_type.inner_type, high - low)
return VecHolder(v_type, vec.conn_side, values)
@slice_(HclType)
def _(_0, *_):
ExprError.op_type_err('slice', _0)
def check_bit_width(uint, high, low):
w = uint.hcl_type.width
# TODO: Accurate Error Message
assert w > high >= low >= 0
def check_vec_size(vec, low, high):
s = vec.hcl_type.size
# TODO: Accurate Error Message
assert 0 <= low < high <= s

View File

@ -1,13 +0,0 @@
from py_hcl.core.stmt.connect import ConnSide
def assert_right_side(f):
def _(*args):
check_lists = [a for a in args if hasattr(a, 'conn_side')]
sides = [ConnSide.RT, ConnSide.BOTH]
# TODO: Accurate Error Message
assert all(a.conn_side in sides for a in check_lists)
return f(*args)
return _

View File

@ -1,12 +0,0 @@
from py_hcl.core.expr import HclExpr
from py_hcl.core.type.vector import VectorT
class VecHolder(HclExpr):
def __init__(self, hcl_type, conn_side, assoc_value):
self.hcl_type = hcl_type
self.conn_side = conn_side
assert isinstance(hcl_type, VectorT)
assert hcl_type.size == len(assoc_value)
self.assoc_value = assoc_value

View File

@ -1,11 +0,0 @@
from py_hcl.core.expr import HclExpr
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.core.type import HclType
from py_hcl.utils import json_serialize
@json_serialize(json_fields=['hcl_type', 'conn_side'])
class Wire(HclExpr):
def __init__(self, hcl_type: HclType):
self.hcl_type = hcl_type
self.conn_side = ConnSide.BOTH

View File

@ -1,72 +0,0 @@
from py_hcl.core.expr import ExprHolder
from py_hcl.core.expr.bundle_holder import BundleHolder
from py_hcl.core.expr.error import ExprError
from py_hcl.core.expr.utils import assert_right_side
from py_hcl.core.expr.vec_holder import VecHolder
from py_hcl.core.hcl_ops import op_register
from py_hcl.core.stmt.connect import ConnSide
from py_hcl.core.type import HclType
from py_hcl.core.type.bundle import BundleT, Dir
from py_hcl.core.type.sint import SIntT
from py_hcl.core.type.uint import UIntT
from py_hcl.core.type.vector import VectorT
from py_hcl.utils import json_serialize
@json_serialize
class Xor(object):
def __init__(self, left, right):
self.operation = 'xor'
self.left_expr_id = left.id
self.right_expr_id = right.id
xorer = op_register('^')
@xorer(UIntT, UIntT)
@assert_right_side
def _(lf, rt):
w = max(lf.hcl_type.width, rt.hcl_type.width)
t = UIntT(w)
return ExprHolder(t, ConnSide.RT, Xor(lf, rt))
@xorer(SIntT, SIntT)
@assert_right_side
def _(lf, rt):
w = max(lf.hcl_type.width, rt.hcl_type.width)
t = UIntT(w)
return ExprHolder(t, ConnSide.RT, Xor(lf, rt))
@xorer(VectorT, VectorT)
@assert_right_side
def _(lf, rt):
# TODO: Accurate Error Message
assert lf.hcl_type.size == rt.hcl_type.size
values = [lf[i] ^ rt[i] for i in range(lf.hcl_type.size)]
v_type = VectorT(values[0].hcl_type, len(values))
return VecHolder(v_type, ConnSide.RT, values)
@xorer(BundleT, BundleT)
@assert_right_side
def _(lf, rt):
# TODO: Accurate Error Message
assert set(lf.hcl_type.fields.keys()) == set(rt.hcl_type.fields.keys())
bd_type_fields = {}
bd_values = {}
for k in lf.hcl_type.fields.keys():
res = getattr(lf, k) ^ getattr(rt, k)
bd_type_fields[k] = {"dir": Dir.SRC, "hcl_type": res.hcl_type}
bd_values[k] = res
return BundleHolder(BundleT(bd_type_fields), ConnSide.RT, bd_values)
@xorer(HclType, HclType)
def _(_0, _1):
raise ExprError.op_type_err('xor', _0, _1)

View File

@ -1,38 +0,0 @@
from multipledispatch import Dispatcher
op_map = {
'+': Dispatcher('+'),
'&': Dispatcher('&'),
'^': Dispatcher('&'),
'|': Dispatcher('|'),
'<<=': Dispatcher('<<='),
'.': Dispatcher('.'),
'[i]': Dispatcher('[i]'),
'[i:j]': Dispatcher('[i:j]'),
'[i:]': Dispatcher('[i:]'),
'[i:j:k]': Dispatcher('[i:j:k]'),
'[i::k]': Dispatcher('[i::k]'),
'to_sint': Dispatcher('to_sint'),
'to_uint': Dispatcher('to_uint'),
'to_bool': Dispatcher('to_bool'),
'extend': Dispatcher('extend'),
}
def op_register(operation):
return op_map[operation].register
def op_apply(operation):
def _(*objects):
types = [type(o.hcl_type) for o in objects if hasattr(o, 'hcl_type')]
func = op_map[operation].dispatch(*types)
if func is not None:
return func(*objects)
msg = 'No matched functions for types {} while calling operation ' \
'"{}"'.format([type(o).__name__ for o in objects], operation)
raise NotImplementedError(msg)
return _

View File

@ -1,9 +0,0 @@
from py_hcl.core import install_ops
from py_hcl.core.expr.io import io_extend
from py_hcl.core.module.meta_module import MetaModule
install_ops()
class BaseModule(metaclass=MetaModule):
io = io_extend(tuple())({})

View File

@ -1,35 +0,0 @@
from py_hcl.core.expr.mod_inst import con_module
from py_hcl.core.module_factory import packer
from py_hcl.core.module_factory.error import ModuleError
class MetaModule(type):
def __init__(cls, name, bases, dct):
if name == '_hcl_fake_module':
return
super().__init__(name, bases, dct)
cls.__new__ = con_module
name = fetch_module_name(name)
check_io_exist(dct, name)
dct["io"].io_chain_head.io_holder.module_name = name
packed = packer.pack(bases, dct, name)
cls.packed_module = packed
module_names = {}
def fetch_module_name(name: str) -> str:
n = module_names.get(name, 0)
module_names[name] = n + 1
return name + ("" if n == 0 else str(n))
def check_io_exist(dct, name):
if 'io' not in dct:
raise ModuleError.not_contains_io(
'module {} lack of io attribute'.format(name))

View File

@ -1,9 +0,0 @@
from py_hcl.utils import json_serialize
@json_serialize
class PackedModule(object):
def __init__(self, name, named_expr_chain, statement_chain):
self.name = name
self.named_expr_chain = named_expr_chain
self.statement_chain = statement_chain

View File

@ -1,18 +0,0 @@
from py_hcl.core.error import CoreError
def set_up():
ModuleError.append({
'NotContainsIO': {
'code': 100,
'value': ModuleError('the module lack of io attribute')},
})
class ModuleError(CoreError):
@staticmethod
def not_contains_io(msg):
return ModuleError.err('NotContainsIO', msg)
set_up()

View File

@ -1,11 +0,0 @@
from py_hcl.core.expr import HclExpr
def extract(dct):
res = {}
for k, v in dct.items():
if isinstance(v, HclExpr):
res[v.id] = k
return res

View File

@ -1,27 +0,0 @@
from typing import Optional, Dict
from py_hcl.utils import json_serialize
@json_serialize
class NamedExprHolder(object):
def __init__(self, module_name: str,
named_expression_table: Dict[int, str]):
self.module_name = module_name
self.named_expression_table = named_expression_table
@json_serialize
class NamedExprNode(object):
def __init__(self,
named_expr_holder: NamedExprHolder,
next_node: Optional["NamedExprNode"]):
self.named_expr_holder = named_expr_holder
if next_node:
self.next_node = next_node
@json_serialize
class NamedExprChain(object):
def __init__(self, named_expr_chain_head: NamedExprNode):
self.named_expr_chain_head = named_expr_chain_head

View File

@ -1,26 +0,0 @@
from typing import Optional
from py_hcl.core.stmt import ClusterStatement
from py_hcl.utils import json_serialize
@json_serialize
class StmtHolder(object):
def __init__(self, module_name: str, top_statement: ClusterStatement):
self.module_name = module_name
self.top_statement = top_statement
@json_serialize
class StmtNode(object):
def __init__(self, stmt_holder: StmtHolder,
next_node: Optional["StmtNode"]):
self.stmt_holder = stmt_holder
if next_node:
self.next_node = next_node
@json_serialize
class StmtChain(object):
def __init__(self, stmt_chain_head: StmtNode):
self.stmt_chain_head = stmt_chain_head

View File

@ -1,30 +0,0 @@
from typing import List
from .inherit_list.named_expr import NamedExprChain, \
NamedExprNode, NamedExprHolder
from .inherit_list.stmt_holder import StmtChain, \
StmtHolder, StmtNode
def merge_expr(modules: List[type],
expr_holder: NamedExprHolder) -> NamedExprChain:
expr_list = None
for m in modules[::-1]:
h = m.packed_module.named_expr_chain \
.named_expr_chain_head.named_expr_holder
expr_list = NamedExprNode(h, expr_list)
expr_list = NamedExprNode(expr_holder, expr_list)
return NamedExprChain(expr_list)
def merge_statement(modules: List[type],
stmt_holder: StmtHolder) -> StmtChain:
stmt_list = None
for m in modules[::-1]:
h = m.packed_module.statement_chain \
.stmt_chain_head.stmt_holder
stmt_list = StmtNode(h, stmt_list)
stmt_list = StmtNode(stmt_holder, stmt_list)
return StmtChain(stmt_list)

View File

@ -1,61 +0,0 @@
from py_hcl.core.module.packed_module import PackedModule
from py_hcl.core.module_factory.inherit_list.named_expr import NamedExprHolder
from py_hcl.core.module_factory.inherit_list.stmt_holder import StmtHolder
from py_hcl.core.stmt_factory.trapper import StatementTrapper
from py_hcl.core.utils import module_inherit_mro
from . import extractor
from . import merger
from ..stmt import ClusterStatement, ConditionStatement
from ..stmt_factory.scope import ScopeType
def pack(bases, dct, name) -> PackedModule:
raw_expr = extractor.extract(dct)
raw_statement = normalize_conditional_branch(StatementTrapper.trap())
named_expr_chain, statement_chain = \
handle_inherit(bases, raw_expr, raw_statement, name)
res = PackedModule(name, named_expr_chain, statement_chain)
return res
def handle_inherit(bases, named_expression, top_statement, name):
modules = module_inherit_mro(bases)
named_expr_chain = \
merger.merge_expr(modules, NamedExprHolder(name, named_expression))
statement_chain = \
merger.merge_statement(modules, StmtHolder(name, top_statement))
return named_expr_chain, statement_chain
def normalize_conditional_branch(cluster_statement: ClusterStatement):
new_statements = []
waiting_when = None
for s in cluster_statement.statements:
if s.stmt_class == 'line':
new_statements.append(s)
continue
normalized = normalize_conditional_branch(s)
if s.scope_info.scope_type == ScopeType.WHEN:
cond_id = normalized.scope_info.tag_object.cond_expr_id
cs = ConditionStatement(cond_id, normalized.statements, None)
new_statements.append(cs)
waiting_when = cs
elif s.scope_info.scope_type == ScopeType.ELSE_WHEN:
cond_id = normalized.scope_info.tag_object.cond_expr_id
cs = ConditionStatement(cond_id, normalized.statements, None)
waiting_when.alt_stmts = [cs]
waiting_when = cs
else:
waiting_when.alt_stmts = normalized.statements
cluster_statement.statements = new_statements
return cluster_statement

View File

@ -1,26 +0,0 @@
from py_hcl.utils import json_serialize
@json_serialize(json_fields=['stmt_class', 'statement'])
class LineStatement(object):
def __init__(self, scope_id, statement):
self.stmt_class = 'line'
self.scope_id = scope_id
self.statement = statement
@json_serialize(json_fields=['stmt_class', 'statements'])
class ClusterStatement(object):
def __init__(self, scope_info, stmts):
self.stmt_class = 'cluster'
self.scope_info = scope_info
self.statements = stmts
@json_serialize
class ConditionStatement(object):
def __init__(self, seq_cond_id, seq_stmts, alt_stmts):
self.stmt_class = 'condition'
self.seq_cond_id = seq_cond_id
self.seq_stmts = seq_stmts
self.alt_stmts = alt_stmts

View File

@ -1,107 +0,0 @@
from py_hcl.core.expr import HclExpr
from py_hcl.core.stmt import ClusterStatement
from py_hcl.core.stmt.error import StatementError
from py_hcl.core.stmt_factory.scope import ScopeManager, ScopeType
from py_hcl.core.stmt_factory.trapper import StatementTrapper
from py_hcl.core.type.uint import UIntT
from py_hcl.utils import json_serialize
@json_serialize
class When(object):
def __init__(self, cond_expr_id: int):
self.cond_expr_id = cond_expr_id
@json_serialize
class ElseWhen(object):
def __init__(self, cond_expr_id: int):
self.cond_expr_id = cond_expr_id
def do_when_enter(cond_expr: HclExpr):
check_bool_expr(cond_expr)
w = When(cond_expr.id)
ScopeManager.expand_scope(ScopeType.WHEN, w)
def do_when_exit():
ScopeManager.shrink_scope()
def do_else_when_enter(cond_expr: HclExpr):
check_bool_expr(cond_expr)
check_branch_syntax()
e = ElseWhen(cond_expr.id)
ScopeManager.expand_scope(ScopeType.ELSE_WHEN, e)
def do_else_when_exit():
ScopeManager.shrink_scope()
def do_otherwise_enter():
check_branch_syntax()
ScopeManager.expand_scope(ScopeType.OTHERWISE)
def do_otherwise_exit():
ScopeManager.shrink_scope()
def check_bool_expr(cond_expr: HclExpr):
if isinstance(cond_expr.hcl_type, UIntT) and cond_expr.hcl_type.width == 1:
return
raise StatementError.wrong_branch_syntax(
'check_bool_expr(): '
'expected bool-type expression')
def check_branch_syntax():
check_exists_pre_stmts()
check_exists_pre_when_block()
check_correct_block_level()
def check_exists_pre_stmts():
if len(StatementTrapper.trapped_stmts[-1]) == 0:
raise StatementError.wrong_branch_syntax(
'check_exists_pre_stmts(): '
'expected when block')
def check_exists_pre_when_block():
last_stmt = StatementTrapper.trapped_stmts[-1][-1]
if isinstance(last_stmt, ClusterStatement):
last_scope = last_stmt.scope_info
last_scope_type = last_scope.scope_type
when = last_scope_type == ScopeType.WHEN
else_when = last_scope_type == ScopeType.ELSE_WHEN
if when or else_when:
return
raise StatementError.wrong_branch_syntax(
'check_exists_pre_when_block(): '
'expected when block or else_when block')
def check_correct_block_level():
last_stmt = StatementTrapper.trapped_stmts[-1][-1]
if isinstance(last_stmt, ClusterStatement):
last_scope = last_stmt.scope_info
current_scope = ScopeManager.current_scope()
last_scope_level = last_scope.scope_level
current_scope_level = current_scope.scope_level
if last_scope_level == current_scope_level + 1:
return
raise StatementError.wrong_branch_syntax(
'check_correct_block_level(): '
'branch block not matched')

View File

@ -1,141 +0,0 @@
import logging
from enum import Enum
from py_hcl.core.hcl_ops import op_register, op_apply
from py_hcl.core.stmt.error import StatementError
from py_hcl.core.stmt_factory.trapper import StatementTrapper
from py_hcl.core.type import HclType
from py_hcl.core.type.bundle import BundleT, Dir
from py_hcl.core.type.sint import SIntT
from py_hcl.core.type.uint import UIntT
from py_hcl.core.type.vector import VectorT
from py_hcl.utils import json_serialize
class ConnSide(Enum):
UNKNOWN = 0
LF = 1
RT = 2
BOTH = 3
@json_serialize
class Connect(object):
def __init__(self, left, right):
self.stmt_type = 'connect'
self.left_expr_id = left.id
self.right_expr_id = right.id
connector = op_register('<<=')
@connector(UIntT, UIntT)
def _(left, right):
check_connect_dir(left, right)
if left.hcl_type.width < right.hcl_type.width:
msg = 'connect(): connecting {} to {} will truncate the bits'.format(
right.hcl_type, left.hcl_type)
logging.warning(msg)
right = right[left.hcl_type.width - 1:0]
if left.hcl_type.width > right.hcl_type.width:
right = op_apply('extend')(right, left.hcl_type.width)
assert left.hcl_type.width == right.hcl_type.width
StatementTrapper.track(Connect(left, right))
return left
@connector(SIntT, SIntT)
def _(left, right):
check_connect_dir(left, right)
if left.hcl_type.width < right.hcl_type.width:
logging.warning(
'connect(): connecting {} to {} will truncate the bits'.format(
right.hcl_type, left.hcl_type
))
right = right[left.hcl_type.width - 1:0].to_sint()
if left.hcl_type.width > right.hcl_type.width:
right = op_apply('extend')(right, left.hcl_type.width)
assert left.hcl_type.width == right.hcl_type.width
StatementTrapper.track(Connect(left, right))
return left
@connector(UIntT, SIntT)
def _(left, right):
msg = 'connect(): connecting SInt to UInt, an auto-conversion will occur'
logging.warning(msg)
if left.hcl_type.width < right.hcl_type.width:
logging.warning(
'connect(): connecting {} to {} will truncate the bits'.format(
right.hcl_type, left.hcl_type
))
return op_apply('<<=')(left, right[left.hcl_type.width - 1:0])
return op_apply('<<=')(left, right.to_uint())
@connector(SIntT, UIntT)
def _(left, right):
msg = 'connect(): connecting UInt to SInt, an auto-conversion will occur'
logging.warning(msg)
if left.hcl_type.width < right.hcl_type.width:
logging.warning(
'connect(): connecting {} to {} will truncate the bits'.format(
right.hcl_type, left.hcl_type
))
right = right[left.hcl_type.width - 1:0]
return op_apply('<<=')(left, right.to_sint())
@connector(BundleT, BundleT)
def _(left, right):
check_connect_dir(left, right)
# TODO: Accurate Error Message
dir_and_types = right.hcl_type.fields
keys = dir_and_types.keys()
assert keys == left.hcl_type.fields.keys()
for k in keys:
lf = op_apply('.')(left, k)
rt = op_apply('.')(right, k)
if dir_and_types[k]['dir'] == Dir.SRC:
op_apply('<<=')(lf, rt)
else:
op_apply('<<=')(rt, lf)
return left
@connector(VectorT, VectorT)
def _(left, right):
check_connect_dir(left, right)
# TODO: Accurate Error Message
assert left.hcl_type.size == right.hcl_type.size
for i in range(left.hcl_type.size):
op_apply('<<=')(left[i], right[i])
return left
@connector(HclType, HclType)
def _(_0, _1):
raise StatementError.connect_type_error(_0, _1)
def check_connect_dir(left, right):
# TODO: Accurate Error Message
assert left.conn_side in (ConnSide.LF, ConnSide.BOTH)
assert right.conn_side in (ConnSide.RT, ConnSide.BOTH)

View File

@ -1,30 +0,0 @@
from py_hcl.core.error import CoreError
def set_up():
StatementError.append({
'WrongBranchSyntax': {
'code': 300,
'value': StatementError(
'expected a well-defined when-else_when-otherwise block')},
'ConnectTypeError': {
'code': 301,
'value': StatementError(
'connect statement contains unexpected types')
}
})
class StatementError(CoreError):
@staticmethod
def wrong_branch_syntax(msg):
return StatementError.err('WrongBranchSyntax', msg)
@staticmethod
def connect_type_error(*args):
ts = ', '.join([type(a.hcl_type).__name__ for a in args])
msg = 'connect(): unsupported connect types: {}'.format(ts)
return StatementError.err('ConnectTypeError', msg)
set_up()

View File

@ -1,106 +0,0 @@
from enum import Enum
from py_hcl.utils import json_serialize
class ScopeType(Enum):
TOP = 0
GROUND = 1
WHEN = 2
ELSE_WHEN = 3
OTHERWISE = 4
@json_serialize
class ScopeInfo(object):
def __init__(self, scope_id, scope_level, scope_type, tag_object=None):
self.scope_id = scope_id
self.scope_level = scope_level
self.scope_type = scope_type
if tag_object:
self.tag_object = tag_object
class ScopeLevelManager(object):
_next_scope_level = 0
@classmethod
def current_level(cls):
return cls._next_scope_level
@classmethod
def expand_level(cls):
cls._next_scope_level += 1
@classmethod
def shrink_level(cls):
cls._next_scope_level -= 1
class ScopeIdManager(object):
_next_scope_id = 0
@classmethod
def next_id(cls):
ret = cls._next_scope_id
cls._next_scope_id += 1
return ret
class ScopeManager(object):
scope_list = [
ScopeInfo(
# TOP SCOPE which contains all modules
scope_id=ScopeIdManager.next_id(),
scope_level=ScopeLevelManager.current_level(),
scope_type=ScopeType.TOP,
)
]
scope_id_map = {
scope_list[0].scope_id: scope_list[0]
}
scope_expanding_hooks = []
scope_shrinking_hooks = []
@classmethod
def expand_scope(cls, scope_type, tag_object=None):
ScopeLevelManager.expand_level()
current_scope = cls.current_scope()
next_id = ScopeIdManager.next_id()
next_scope = ScopeInfo(
scope_id=next_id,
scope_level=ScopeLevelManager.current_level(),
scope_type=scope_type,
tag_object=tag_object,
)
cls.scope_id_map[next_id] = next_scope
cls.scope_list.append(next_scope)
for fn in cls.scope_expanding_hooks:
fn(current_scope, next_scope)
@classmethod
def shrink_scope(cls):
ScopeLevelManager.shrink_level()
current_scope = cls.scope_list.pop()
next_scope = cls.current_scope()
for fn in cls.scope_shrinking_hooks:
fn(current_scope, next_scope)
@classmethod
def current_scope(cls):
return cls.scope_list[-1]
@classmethod
def get_scope_info(cls, sid):
return cls.scope_id_map[sid]
@classmethod
def register_scope_expanding(cls, fn):
cls.scope_expanding_hooks.append(fn)
@classmethod
def register_scope_shrinking(cls, fn):
cls.scope_shrinking_hooks.append(fn)

View File

@ -1,47 +0,0 @@
from py_hcl.core.stmt import LineStatement, ClusterStatement
from .scope import ScopeManager, ScopeType
def set_up():
ScopeManager.register_scope_expanding(
StatementTrapper.on_scope_expanding)
ScopeManager.register_scope_shrinking(
StatementTrapper.on_scope_shrinking)
ScopeManager.expand_scope(ScopeType.GROUND)
class StatementTrapper(object):
trapped_stmts = [[
# TOP SCOPE which contains all modules
]]
@classmethod
def trap(cls):
ScopeManager.shrink_scope()
assert len(cls.trapped_stmts) == 1
ret = cls.trapped_stmts[0][-1]
ScopeManager.expand_scope(ScopeType.GROUND)
return ret # TODO
@classmethod
def track(cls, statement):
statement = LineStatement(
ScopeManager.current_scope().scope_id,
statement
)
cls.trapped_stmts[-1].append(statement)
@classmethod
def on_scope_expanding(cls, current_scope, next_scope):
cls.trapped_stmts.append([])
@classmethod
def on_scope_shrinking(cls, current_scope, next_scope):
stmts = cls.trapped_stmts.pop()
cls.trapped_stmts[-1].append(ClusterStatement(current_scope, stmts))
set_up()

View File

@ -1,10 +0,0 @@
from py_hcl.utils import json_serialize
@json_serialize
class HclType(object):
pass
class UnknownType(HclType):
pass

View File

@ -1,18 +0,0 @@
from enum import Enum
from typing import Dict
from py_hcl.core.type import HclType
from py_hcl.core.type.wrapper import vec_wrap, bd_fld_wrap
class Dir(Enum):
SRC = 1
SINK = 2
@bd_fld_wrap
@vec_wrap
class BundleT(HclType):
def __init__(self, fields: Dict[str, dict]):
self.type = "bundle"
self.fields = fields

View File

@ -1,6 +0,0 @@
from py_hcl.core.type import HclType
class ClockT(HclType):
def __init__(self):
self.type = "clock"

View File

@ -1,20 +0,0 @@
from py_hcl.core.type import HclType
from py_hcl.core.type.wrapper import bd_fld_wrap, vec_wrap
from py_hcl.utils import signed_num_bin_len
@bd_fld_wrap
@vec_wrap
class SIntT(HclType):
def __init__(self, width):
self.type = "sint"
self.width = width
def __call__(self, value: int):
from py_hcl.core.expr.lit_sint import SLiteral
# TODO: Accurate Error Message
assert signed_num_bin_len(value) <= self.width
u = SLiteral(value)
u.hcl_type = SIntT(self.width)
return u

View File

@ -1,20 +0,0 @@
from py_hcl.core.type import HclType
from py_hcl.core.type.wrapper import bd_fld_wrap, vec_wrap
from py_hcl.utils import unsigned_num_bin_len
@bd_fld_wrap
@vec_wrap
class UIntT(HclType):
def __init__(self, width):
self.type = "uint"
self.width = width
def __call__(self, value: int):
from py_hcl.core.expr.lit_uint import ULiteral
# TODO: Accurate Error Message
assert unsigned_num_bin_len(value) <= self.width
u = ULiteral(value)
u.hcl_type = UIntT(self.width)
return u

Some files were not shown because too many files have changed in this diff Show More