Skip to content

Commit

Permalink
Replace logic by wire for always_comb-less assigns
Browse files Browse the repository at this point in the history
Also removed reset! :D
  • Loading branch information
VonTum committed Jul 26, 2024
1 parent dceee87 commit f9a5f05
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 37 deletions.
38 changes: 18 additions & 20 deletions bitSerialMatrixMultiply.sus
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@

// Just a wrapper to reduce IOs for small FPGA synthesis. Barely enough logic to make the optimizer not optimize it out. The proper one requires too many IOs
module BitSerialMatrixMultiplyTinyIO {
interface BitSerialMatrixMultiplyTinyIO : bool start, bool rst, int value, int addr -> int result
interface BitSerialMatrixMultiplyTinyIO : bool start, int value -> bool finish, int result

BitSerialMatrixMultiply bsmm

state int[10] stored_values
stored_values[addr] = value
int[15] r = bsmm(start, stored_values)
bsmm.rst = rst
state int last_value_use_as_addr
last_value_use_as_addr = value
stored_values[last_value_use_as_addr] = value
finish, int[15] r = bsmm(start, stored_values)

result = r[addr]
result = r[last_value_use_as_addr]
}


Expand All @@ -30,11 +31,10 @@ module BitSerialMatrixMultiply {

BitSerialMatrixMultiplyTemplate::<WIDTH = 10, HEIGHT = 15, MATRIX = MATRIX;> bsmm

interface BitSerialMatrixMultiply : bool start, int[10] values -> int[15] result
input bool rst
interface BitSerialMatrixMultiply : bool start, int[10] values -> bool finish'36, int[15] result'36
finish = start

result = bsmm(start, values)
bsmm.rst = rst
}


Expand All @@ -51,7 +51,6 @@ module BitSerialMatrixMultiplyTemplate {
BitSerialMatrixMultiplyState::<WIDTH, HEIGHT, MATRIX;> bsm_state

interface BitSerialMatrixMultiplyTemplate : bool start, int[WIDTH] values -> int[HEIGHT] result
input bool rst

state bool[WIDTH][INT_BITWIDTH] split_into_bits

Expand All @@ -60,22 +59,21 @@ module BitSerialMatrixMultiplyTemplate {
// Explicitly not use value
int _ = iter.value

iter.rst = rst

// This is above start, so start has write priority on split_into_bits. TODO shift down once we have `overwrite`
if iter.valid {
// It's a shift register
for int BIT in 0..INT_BITWIDTH-1 {
split_into_bits[BIT] = split_into_bits[BIT + 1]
for int BIT in 1..INT_BITWIDTH {
split_into_bits[BIT] = split_into_bits[BIT - 1]
}

bsm_state.feed(true, split_into_bits[0])
bsm_state.feed(true, split_into_bits[INT_BITWIDTH-1])
} else {
bsm_state.feed(false, split_into_bits[0])
bsm_state.feed(false, split_into_bits[INT_BITWIDTH-1])
}

result = LatencyOffset::<INT_BITWIDTH;int[HEIGHT]>(bsm_state.finish(iter.last))
result = LatencyOffset::<INT_BITWIDTH+1;int[HEIGHT]>(bsm_state.result_vector)

bsm_state.start(start)
iter.start(start)
if start {
// initialize split_into_bits
Expand All @@ -95,20 +93,20 @@ module BitSerialMatrixMultiplyState {

input gen int[WIDTH][HEIGHT] MATRIX

interface start : bool start

interface feed : bool feed, bool[WIDTH] vector_bits

interface finish : bool finish -> state int[HEIGHT] result_vector
output state int[HEIGHT] result_vector

for int Y in 0..HEIGHT {
initial result_vector[Y] = 0

BitSerialRow::<SIZE = WIDTH, WEIGHTS = MATRIX[Y];> row

if feed {
result_vector[Y] = result_vector[Y] * 2 + row(vector_bits)
}

if finish {
if start {
result_vector[Y] = 0
}
}
Expand Down
30 changes: 17 additions & 13 deletions src/codegen_fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub fn mangle(str: &str) -> String {

/// Creates the Verilog variable declaration for tbis variable.
///
/// IE for `int[15] myVar` it creates `logic[31:0] myVar[14:0]`
/// IE for `int[15] myVar` it creates `[31:0] myVar[14:0]`
fn typ_to_declaration(mut typ: &ConcreteType, var_name: &str) -> String {
let mut array_string = String::new();
while let ConcreteType::Array(arr) = typ {
Expand All @@ -48,9 +48,9 @@ fn typ_to_declaration(mut typ: &ConcreteType, var_name: &str) -> String {
ConcreteType::Named(id) => {
let sz = get_type_name_size(*id);
if sz == 1 {
format!("logic{array_string} {var_name}")
format!("{array_string} {var_name}")
} else {
format!("logic{array_string}[{}:0] {var_name}", sz - 1)
format!("{array_string}[{}:0] {var_name}", sz - 1)
}
}
ConcreteType::Array(_) => unreachable!("All arrays have been used up already"),
Expand All @@ -62,7 +62,11 @@ fn wire_name_with_latency(wire: &RealWire, absolute_latency: i64, use_latency: b
assert!(wire.absolute_latency <= absolute_latency);

if use_latency && (wire.absolute_latency != absolute_latency) {
Cow::Owned(format!("{}_D{}", wire.name, absolute_latency))
if absolute_latency < 0 {
Cow::Owned(format!("_{}_N{}", wire.name, -absolute_latency))
} else {
Cow::Owned(format!("_{}_D{}", wire.name, absolute_latency))
}
} else {
Cow::Borrowed(&wire.name)
}
Expand Down Expand Up @@ -137,7 +141,7 @@ impl<'g, 'out, Stream: std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>

writeln!(
self.program_text,
"/*latency*/ {var_decl}; always_ff @(posedge clk) begin {to} <= {from}; end"
"/*latency*/ logic {var_decl}; always_ff @(posedge clk) begin {to} <= {from}; end"
).unwrap();
}
}
Expand Down Expand Up @@ -173,12 +177,12 @@ impl<'g, 'out, Stream: std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
for (_id, port) in self.instance.interface_ports.iter_valids() {
let port_wire = &self.instance.wires[port.wire];
let input_or_output = if port.is_input { "input" } else { "output" };
let wire_doc = port_wire.source.get_sv_info_doc();
let wire_doc = port_wire.source.wire_or_reg();
let wire_name = wire_name_self_latency(port_wire, self.use_latency);
let wire_decl = typ_to_declaration(&port_wire.typ, &wire_name);
write!(
self.program_text,
",\n{comment_text}\t{wire_doc}{input_or_output} {wire_decl}"
",\n{comment_text}\t{input_or_output} {wire_doc} {wire_decl}"
).unwrap();
}
write!(self.program_text, "\n{comment_text});\n\n").unwrap();
Expand Down Expand Up @@ -223,11 +227,11 @@ impl<'g, 'out, Stream: std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
continue;
}
}
let wire_or_reg = w.source.get_sv_info_doc();
let wire_or_reg = w.source.wire_or_reg();

let wire_name = wire_name_self_latency(w, self.use_latency);
let wire_decl = typ_to_declaration(&w.typ, &wire_name);
write!(self.program_text, "{wire_or_reg}{wire_decl}").unwrap();
write!(self.program_text, "{wire_or_reg} {wire_decl}").unwrap();

match &w.source {
RealWireDataSource::Select { root, path } => {
Expand Down Expand Up @@ -412,17 +416,17 @@ impl Module {
}

impl RealWireDataSource {
fn get_sv_info_doc(&self) -> &str {
fn wire_or_reg(&self) -> &str {
match self {
RealWireDataSource::Multiplexer {
is_state: Some(_),
sources: _,
} => "/*state*/ ",
} => "/*state*/ logic",
RealWireDataSource::Multiplexer {
is_state: None,
sources: _,
} => "/*mux_wire*/ ",
_ => "",
} => "/*mux_wire*/ logic",
_ => "wire",
}
}
}
Expand Down
5 changes: 1 addition & 4 deletions util.sus
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,10 @@ module FixedSizeIterator {

interface start : bool start

input bool rst


last = value == UP_TO - 1
valid = value != UP_TO

if start | rst {
if start {
value = 0
} else {
if valid {
Expand Down

0 comments on commit f9a5f05

Please sign in to comment.