Skip to content

Commit

Permalink
Merge branch 'dev' into feature/pyxsi_integration
Browse files Browse the repository at this point in the history
  • Loading branch information
auphelia committed Jan 8, 2025
2 parents 6522c49 + 30e0d02 commit 0e7dfd3
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 107 deletions.
144 changes: 72 additions & 72 deletions finn-rtllib/fifo/hdl/Q_srl.v
Original file line number Diff line number Diff line change
Expand Up @@ -184,58 +184,58 @@ module Q_srl (clock, reset, i_d, i_v, i_r, o_d, o_v, o_r, count, maxcount);
end // always @ (posedge clock or negedge reset)

always @* begin // - combi always
srlo_ <= 'bx;
shift_en_o_ <= 1'bx;
shift_en_ <= 1'bx;
addr_ <= 'bx;
state_ <= 2'bx;
srlo_ = 'bx;
shift_en_o_ = 1'bx;
shift_en_ = 1'bx;
addr_ = 'bx;
state_ = 2'bx;
case (state)

state_empty: begin // - (empty, will not produce)
if (i_v) begin // - empty & i_v => consume
srlo_ <= i_d;
shift_en_o_ <= 1;
shift_en_ <= 1'bx;
addr_ <= 0;
state_ <= state_one;
srlo_ = i_d;
shift_en_o_ = 1;
shift_en_ = 1'bx;
addr_ = 0;
state_ = state_one;
end
else begin // - empty & !i_v => idle
srlo_ <= 'bx;
shift_en_o_ <= 0;
shift_en_ <= 1'bx;
addr_ <= 0;
state_ <= state_empty;
srlo_ = 'bx;
shift_en_o_ = 0;
shift_en_ = 1'bx;
addr_ = 0;
state_ = state_empty;
end
end

state_one: begin // - (contains one)
if (i_v && o_b) begin // - one & i_v & o_b => consume
srlo_ <= 'bx;
shift_en_o_ <= 0;
shift_en_ <= 1;
addr_ <= 0;
state_ <= state_more;
srlo_ = 'bx;
shift_en_o_ = 0;
shift_en_ = 1;
addr_ = 0;
state_ = state_more;
end
else if (i_v && !o_b) begin // - one & i_v & !o_b => cons+prod
srlo_ <= i_d;
shift_en_o_ <= 1;
shift_en_ <= 1;
addr_ <= 0;
state_ <= state_one;
srlo_ = i_d;
shift_en_o_ = 1;
shift_en_ = 1;
addr_ = 0;
state_ = state_one;
end
else if (!i_v && o_b) begin // - one & !i_v & o_b => idle
srlo_ <= 'bx;
shift_en_o_ <= 0;
shift_en_ <= 1'bx;
addr_ <= 0;
state_ <= state_one;
srlo_ = 'bx;
shift_en_o_ = 0;
shift_en_ = 1'bx;
addr_ = 0;
state_ = state_one;
end
else if (!i_v && !o_b) begin // - one & !i_v & !o_b => produce
srlo_ <= 'bx;
shift_en_o_ <= 0;
shift_en_ <= 1'bx;
addr_ <= 0;
state_ <= state_empty;
srlo_ = 'bx;
shift_en_o_ = 0;
shift_en_ = 1'bx;
addr_ = 0;
state_ = state_empty;
end
end // case: state_one

Expand All @@ -244,60 +244,60 @@ module Q_srl (clock, reset, i_d, i_v, i_r, o_d, o_v, o_r, count, maxcount);
// - (full, will not consume)
// - (full here if depth==2)
if (o_b) begin // - full & o_b => idle
srlo_ <= 'bx;
shift_en_o_ <= 0;
shift_en_ <= 0;
addr_ <= addr;
state_ <= state_more;
srlo_ = 'bx;
shift_en_o_ = 0;
shift_en_ = 0;
addr_ = addr;
state_ = state_more;
end
else begin // - full & !o_b => produce
srlo_ <= srl[addr];
shift_en_o_ <= 1;
shift_en_ <= 0;
// addr_ <= addr-1;
// state_ <= state_more;
addr_ <= addr_zero_ ? 0 : addr-1;
state_ <= addr_zero_ ? state_one : state_more;
srlo_ = srl[addr];
shift_en_o_ = 1;
shift_en_ = 0;
// addr_ = addr-1;
// state_ = state_more;
addr_ = addr_zero_ ? 0 : addr-1;
state_ = addr_zero_ ? state_one : state_more;
end
end
else begin // - (mid: neither empty nor full)
if (i_v && o_b) begin // - mid & i_v & o_b => consume
srlo_ <= 'bx;
shift_en_o_ <= 0;
shift_en_ <= 1;
addr_ <= addr+1;
state_ <= state_more;
srlo_ = 'bx;
shift_en_o_ = 0;
shift_en_ = 1;
addr_ = addr+1;
state_ = state_more;
end
else if (i_v && !o_b) begin // - mid & i_v & !o_b => cons+prod
srlo_ <= srl[addr];
shift_en_o_ <= 1;
shift_en_ <= 1;
addr_ <= addr;
state_ <= state_more;
srlo_ = srl[addr];
shift_en_o_ = 1;
shift_en_ = 1;
addr_ = addr;
state_ = state_more;
end
else if (!i_v && o_b) begin // - mid & !i_v & o_b => idle
srlo_ <= 'bx;
shift_en_o_ <= 0;
shift_en_ <= 0;
addr_ <= addr;
state_ <= state_more;
srlo_ = 'bx;
shift_en_o_ = 0;
shift_en_ = 0;
addr_ = addr;
state_ = state_more;
end
else if (!i_v && !o_b) begin // - mid & !i_v & !o_b => produce
srlo_ <= srl[addr];
shift_en_o_ <= 1;
shift_en_ <= 0;
addr_ <= addr_zero_ ? 0 : addr-1;
state_ <= addr_zero_ ? state_one : state_more;
srlo_ = srl[addr];
shift_en_o_ = 1;
shift_en_ = 0;
addr_ = addr_zero_ ? 0 : addr-1;
state_ = addr_zero_ ? state_one : state_more;
end
end // else: !if(addr_full)
end // case: state_more

default: begin
srlo_ <= 'bx;
shift_en_o_ <= 1'bx;
shift_en_ <= 1'bx;
addr_ <= 'bx;
state_ <= 2'bx;
srlo_ = 'bx;
shift_en_o_ = 1'bx;
shift_en_ = 1'bx;
addr_ = 'bx;
state_ = 2'bx;
end // case: default

endcase // case(state)
Expand Down
112 changes: 83 additions & 29 deletions src/finn/custom_op/fpgadataflow/hlsbackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ def get_nodeattr_types(self):
"code_gen_dir_cppsim": ("s", False, ""),
"executable_path": ("s", False, ""),
"res_hls": ("s", False, ""),
# temporary node attribute to keep track of interface style of hls ops
"cpp_interface": ("s", False, "packed", {"packed", "hls_vector"}),
}

def get_all_verilog_paths(self):
Expand Down Expand Up @@ -232,7 +234,13 @@ def code_generation_cppsim(self, model):
self.dataoutstrm()
self.save_as_npy()

template = templates.docompute_template
if self.get_nodeattr("cpp_interface") == "hls_vector":
self.timeout_value()
self.timeout_condition()
self.timeout_read_stream()
template = templates.docompute_template_timeout
else:
template = templates.docompute_template

for key in self.code_gen_dict:
# transform list into long string separated by '\n'
Expand Down Expand Up @@ -398,24 +406,40 @@ def read_npy_data(self):
if dtype == DataType["BIPOLAR"]:
# use binary for bipolar storage
dtype = DataType["BINARY"]
elem_bits = dtype.bitwidth()
packed_bits = self.get_instream_width()
packed_hls_type = "ap_uint<%d>" % packed_bits
elem_hls_type = dtype.get_hls_datatype_str()
npy_type = "float"
npy_in = "%s/input_0.npy" % code_gen_dir
self.code_gen_dict["$READNPYDATA$"] = []
self.code_gen_dict["$READNPYDATA$"].append(
'npy2apintstream<%s, %s, %d, %s>("%s", in0_%s);'
% (
packed_hls_type,
elem_hls_type,
elem_bits,
npy_type,
npy_in,
self.hls_sname(),

cpp_interface = self.get_nodeattr("cpp_interface")

if cpp_interface == "packed":
elem_bits = dtype.bitwidth()
packed_bits = self.get_instream_width()
packed_hls_type = "ap_uint<%d>" % packed_bits
self.code_gen_dict["$READNPYDATA$"].append(
'npy2apintstream<%s, %s, %d, %s>("%s", in0_%s);'
% (
packed_hls_type,
elem_hls_type,
elem_bits,
npy_type,
npy_in,
self.hls_sname(),
)
)
else:
folded_shape = self.get_folded_input_shape()
self.code_gen_dict["$READNPYDATA$"].append(
'npy2vectorstream<%s, %s, %d>("%s", in0_%s, false);'
% (
elem_hls_type,
npy_type,
folded_shape[-1],
npy_in,
self.hls_sname(),
)
)
)

def strm_decl(self):
"""Function to generate the commands for the stream declaration in c++,
Expand Down Expand Up @@ -449,27 +473,43 @@ def dataoutstrm(self):
if dtype == DataType["BIPOLAR"]:
# use binary for bipolar storage
dtype = DataType["BINARY"]
elem_bits = dtype.bitwidth()
packed_bits = self.get_outstream_width()
packed_hls_type = "ap_uint<%d>" % packed_bits
elem_hls_type = dtype.get_hls_datatype_str()
npy_type = "float"
npy_out = "%s/output.npy" % code_gen_dir
oshape = self.get_folded_output_shape()
oshape_cpp_str = str(oshape).replace("(", "{").replace(")", "}")

self.code_gen_dict["$DATAOUTSTREAM$"] = [
'apintstream2npy<%s, %s, %d, %s>(out_%s, %s, "%s");'
% (
packed_hls_type,
elem_hls_type,
elem_bits,
npy_type,
self.hls_sname(),
oshape_cpp_str,
npy_out,
)
]
cpp_interface = self.get_nodeattr("cpp_interface")

if cpp_interface == "packed":
elem_bits = dtype.bitwidth()
packed_bits = self.get_outstream_width()
packed_hls_type = "ap_uint<%d>" % packed_bits

self.code_gen_dict["$DATAOUTSTREAM$"] = [
'apintstream2npy<%s, %s, %d, %s>(out_%s, %s, "%s");'
% (
packed_hls_type,
elem_hls_type,
elem_bits,
npy_type,
self.hls_sname(),
oshape_cpp_str,
npy_out,
)
]
else:
folded_shape = self.get_folded_output_shape()
self.code_gen_dict["$DATAOUTSTREAM$"] = [
'vectorstream2npy<%s, %s, %d>(strm, %s, "%s");'
% (
elem_hls_type,
npy_type,
folded_shape[-1],
oshape_cpp_str,
npy_out,
)
]

def save_as_npy(self):
"""Function to generate the commands for saving data in .npy file in c++"""
Expand Down Expand Up @@ -501,3 +541,17 @@ def get_ap_int_max_w(self):
ret = max([instream, outstream])
assert ret <= 8191, "AP_INT_MAX_W=%d is larger than allowed maximum of 8191" % ret
return ret

def timeout_value(self):
"""Set timeout value for HLS functions defined for one clock cycle"""
self.code_gen_dict["$TIMEOUT_VALUE$"] = ["1000"]

def timeout_condition(self):
"""Set timeout condition for HLS functions defined for one clock cycle"""
self.code_gen_dict["$TIMEOUT_CONDITION$"] = ["out_{}.empty()".format(self.hls_sname())]

def timeout_read_stream(self):
"""Set reading output stream procedure for HLS functions defined for one clock cycle"""
self.code_gen_dict["$TIMEOUT_READ_STREAM$"] = [
"strm << out_{}.read();".format(self.hls_sname())
]
Loading

0 comments on commit 0e7dfd3

Please sign in to comment.