From 73725e716d1d7055feeb8765602bfa7055ad3ed2 Mon Sep 17 00:00:00 2001 From: Mateusz Gancarz Date: Fri, 14 Feb 2025 09:27:57 +0100 Subject: [PATCH] [#72179] change SAIF example to gcd --- examples/saif_example/counter.v | 51 -- examples/saif_example/gcd.v | 755 ++++++++++++++++++ examples/saif_example/saif_trace.cpp | 13 +- .../saif_example/saif_trace_example/config.mk | 2 +- .../src/saif_trace_example/counter.v | 51 -- .../saif_example/src/saif_trace_example/gcd.v | 755 ++++++++++++++++++ 6 files changed, 1521 insertions(+), 106 deletions(-) delete mode 100644 examples/saif_example/counter.v create mode 100644 examples/saif_example/gcd.v delete mode 100644 examples/saif_example/src/saif_trace_example/counter.v create mode 100644 examples/saif_example/src/saif_trace_example/gcd.v diff --git a/examples/saif_example/counter.v b/examples/saif_example/counter.v deleted file mode 100644 index 9cf1356cd..000000000 --- a/examples/saif_example/counter.v +++ /dev/null @@ -1,51 +0,0 @@ -// DESCRIPTION: Verilator: Verilog Test module -// -// Copyright 2025 by Antmicro. This program is free software; you can -// redistribute it and/or modify it under the terms of either the GNU -// Lesser General Public License Version 3 or the Perl Artistic License -// Version 2.0. -// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 - -module t ( - // Outputs - state, - // Inputs - clk); - - input clk; - reg rst; - output [7:0] state; - - counter c0 ( - .clk (clk), - .rst (rst), - .out (state)); - - int cyc; - - always @ (posedge clk) begin - cyc <= cyc + 1; - if (cyc == 0) begin - rst <= 1; - end - else if (cyc == 10) begin - rst <= 0; - end - else if (cyc == 11) begin - rst <= 1; - end - end -endmodule - -module counter ( - input clk, - input rst, - output reg[7:0] out); - - always @ (posedge clk) begin - if (!rst) - out <= 0; - else - out <= out + 1; - end -endmodule diff --git a/examples/saif_example/gcd.v b/examples/saif_example/gcd.v new file mode 100644 index 000000000..cca5856b3 --- /dev/null +++ b/examples/saif_example/gcd.v @@ -0,0 +1,755 @@ +//----------------------------------------------------------------------------- +// GcdUnit +//----------------------------------------------------------------------------- +// +// Originally Generated from PyMTL with a few modifications to make it more +// friendly to OpenROAD tools + +//module GcdUnit +module gcd +( + input wire clk, + input wire [ 31:0] req_msg, + output wire req_rdy, + input wire req_val, + input wire reset, + output wire [ 15:0] resp_msg, + input wire resp_rdy, + output wire resp_val +); + + // ctrl temporaries + wire [ 0:0] ctrl$is_b_zero; + wire [ 0:0] ctrl$resp_rdy; + wire [ 0:0] ctrl$clk; + wire [ 0:0] ctrl$is_a_lt_b; + wire [ 0:0] ctrl$req_val; + wire [ 0:0] ctrl$reset; + wire [ 1:0] ctrl$a_mux_sel; + wire [ 0:0] ctrl$resp_val; + wire [ 0:0] ctrl$b_mux_sel; + wire [ 0:0] ctrl$b_reg_en; + wire [ 0:0] ctrl$a_reg_en; + wire [ 0:0] ctrl$req_rdy; + + GcdUnitCtrlRTL_0x4d0fc71ead8d3d9e ctrl + ( + .is_b_zero ( ctrl$is_b_zero ), + .resp_rdy ( ctrl$resp_rdy ), + .clk ( ctrl$clk ), + .is_a_lt_b ( ctrl$is_a_lt_b ), + .req_val ( ctrl$req_val ), + .reset ( ctrl$reset ), + .a_mux_sel ( ctrl$a_mux_sel ), + .resp_val ( ctrl$resp_val ), + .b_mux_sel ( ctrl$b_mux_sel ), + .b_reg_en ( ctrl$b_reg_en ), + .a_reg_en ( ctrl$a_reg_en ), + .req_rdy ( ctrl$req_rdy ) + ); + + // dpath temporaries + wire [ 1:0] dpath$a_mux_sel; + wire [ 0:0] dpath$clk; + wire [ 15:0] dpath$req_msg_b; + wire [ 15:0] dpath$req_msg_a; + wire [ 0:0] dpath$b_mux_sel; + wire [ 0:0] dpath$reset; + wire [ 0:0] dpath$b_reg_en; + wire [ 0:0] dpath$a_reg_en; + wire [ 0:0] dpath$is_b_zero; + wire [ 15:0] dpath$resp_msg; + wire [ 0:0] dpath$is_a_lt_b; + + GcdUnitDpathRTL_0x4d0fc71ead8d3d9e dpath + ( + .a_mux_sel ( dpath$a_mux_sel ), + .clk ( dpath$clk ), + .req_msg_b ( dpath$req_msg_b ), + .req_msg_a ( dpath$req_msg_a ), + .b_mux_sel ( dpath$b_mux_sel ), + .reset ( dpath$reset ), + .b_reg_en ( dpath$b_reg_en ), + .a_reg_en ( dpath$a_reg_en ), + .is_b_zero ( dpath$is_b_zero ), + .resp_msg ( dpath$resp_msg ), + .is_a_lt_b ( dpath$is_a_lt_b ) + ); + + // signal connections + assign ctrl$clk = clk; + assign ctrl$is_a_lt_b = dpath$is_a_lt_b; + assign ctrl$is_b_zero = dpath$is_b_zero; + assign ctrl$req_val = req_val; + assign ctrl$reset = reset; + assign ctrl$resp_rdy = resp_rdy; + assign dpath$a_mux_sel = ctrl$a_mux_sel; + assign dpath$a_reg_en = ctrl$a_reg_en; + assign dpath$b_mux_sel = ctrl$b_mux_sel; + assign dpath$b_reg_en = ctrl$b_reg_en; + assign dpath$clk = clk; + assign dpath$req_msg_a = req_msg[31:16]; + assign dpath$req_msg_b = req_msg[15:0]; + assign dpath$reset = reset; + assign req_rdy = ctrl$req_rdy; + assign resp_msg = dpath$resp_msg; + assign resp_val = ctrl$resp_val; + + + +endmodule // GcdUnit + +//----------------------------------------------------------------------------- +// GcdUnitCtrlRTL_0x4d0fc71ead8d3d9e +//----------------------------------------------------------------------------- + + +module GcdUnitCtrlRTL_0x4d0fc71ead8d3d9e +( + output reg [ 1:0] a_mux_sel, + output reg [ 0:0] a_reg_en, + output reg [ 0:0] b_mux_sel, + output reg [ 0:0] b_reg_en, + input wire [ 0:0] clk, + input wire [ 0:0] is_a_lt_b, + input wire [ 0:0] is_b_zero, + output reg [ 0:0] req_rdy, + input wire [ 0:0] req_val, + input wire [ 0:0] reset, + input wire [ 0:0] resp_rdy, + output reg [ 0:0] resp_val +); + + // register declarations + reg [ 1:0] curr_state__0; + reg [ 1:0] current_state__1; + reg [ 0:0] do_sub; + reg [ 0:0] do_swap; + reg [ 1:0] next_state__0; + reg [ 1:0] state$in_; + + // localparam declarations + localparam A_MUX_SEL_B = 2; + localparam A_MUX_SEL_IN = 0; + localparam A_MUX_SEL_SUB = 1; + localparam A_MUX_SEL_X = 0; + localparam B_MUX_SEL_A = 0; + localparam B_MUX_SEL_IN = 1; + localparam B_MUX_SEL_X = 0; + localparam STATE_CALC = 1; + localparam STATE_DONE = 2; + localparam STATE_IDLE = 0; + + // state temporaries + wire [ 0:0] state$reset; + wire [ 0:0] state$clk; + wire [ 1:0] state$out; + + RegRst_0x9f365fdf6c8998a state + ( + .reset ( state$reset ), + .in_ ( state$in_ ), + .clk ( state$clk ), + .out ( state$out ) + ); + + // signal connections + assign state$clk = clk; + assign state$reset = reset; + + + // PYMTL SOURCE: + // + // @s.combinational + // def state_transitions(): + // + // curr_state = s.state.out + // next_state = s.state.out + // + // # Transistions out of IDLE state + // + // if ( curr_state == s.STATE_IDLE ): + // if ( s.req_val and s.req_rdy ): + // next_state = s.STATE_CALC + // + // # Transistions out of CALC state + // + // if ( curr_state == s.STATE_CALC ): + // if ( not s.is_a_lt_b and s.is_b_zero ): + // next_state = s.STATE_DONE + // + // # Transistions out of DONE state + // + // if ( curr_state == s.STATE_DONE ): + // if ( s.resp_val and s.resp_rdy ): + // next_state = s.STATE_IDLE + // + // s.state.in_.value = next_state + + // logic for state_transitions() + always @ (*) begin + curr_state__0 = state$out; + next_state__0 = state$out; + if ((curr_state__0 == STATE_IDLE)) begin + if ((req_val&&req_rdy)) begin + next_state__0 = STATE_CALC; + end + else begin + end + end + else begin + end + if ((curr_state__0 == STATE_CALC)) begin + if ((!is_a_lt_b&&is_b_zero)) begin + next_state__0 = STATE_DONE; + end + else begin + end + end + else begin + end + if ((curr_state__0 == STATE_DONE)) begin + if ((resp_val&&resp_rdy)) begin + next_state__0 = STATE_IDLE; + end + else begin + end + end + else begin + end + state$in_ = next_state__0; + end + + // PYMTL SOURCE: + // + // @s.combinational + // def state_outputs(): + // + // current_state = s.state.out + // + // # In IDLE state we simply wait for inputs to arrive and latch them + // + // if current_state == s.STATE_IDLE: + // s.req_rdy.value = 1 + // s.resp_val.value = 0 + // s.a_mux_sel.value = A_MUX_SEL_IN + // s.a_reg_en.value = 1 + // s.b_mux_sel.value = B_MUX_SEL_IN + // s.b_reg_en.value = 1 + // + // # In CALC state we iteratively swap/sub to calculate GCD + // + // elif current_state == s.STATE_CALC: + // + // s.do_swap.value = s.is_a_lt_b + // s.do_sub.value = ~s.is_b_zero + // + // s.req_rdy.value = 0 + // s.resp_val.value = 0 + // s.a_mux_sel.value = A_MUX_SEL_B if s.do_swap else A_MUX_SEL_SUB + // s.a_reg_en.value = 1 + // s.b_mux_sel.value = B_MUX_SEL_A + // s.b_reg_en.value = s.do_swap + // + // # In DONE state we simply wait for output transaction to occur + // + // elif current_state == s.STATE_DONE: + // s.req_rdy.value = 0 + // s.resp_val.value = 1 + // s.a_mux_sel.value = A_MUX_SEL_X + // s.a_reg_en.value = 0 + // s.b_mux_sel.value = B_MUX_SEL_X + // s.b_reg_en.value = 0 + // + // # Default case that we should not hit + // + // else: + // s.req_rdy.value = 0 + // s.resp_val.value = 0 + // s.a_mux_sel.value = A_MUX_SEL_X + // s.a_reg_en.value = 0 + // s.b_mux_sel.value = B_MUX_SEL_X + // s.b_reg_en.value = 0 + + // logic for state_outputs() + always @ (*) begin + current_state__1 = state$out; + if ((current_state__1 == STATE_IDLE)) begin + req_rdy = 1; + resp_val = 0; + a_mux_sel = A_MUX_SEL_IN; + a_reg_en = 1; + b_mux_sel = B_MUX_SEL_IN; + b_reg_en = 1; + end + else begin + if ((current_state__1 == STATE_CALC)) begin + do_swap = is_a_lt_b; + do_sub = ~is_b_zero; + req_rdy = 0; + resp_val = 0; + a_mux_sel = do_swap ? A_MUX_SEL_B : A_MUX_SEL_SUB; + a_reg_en = 1; + b_mux_sel = B_MUX_SEL_A; + b_reg_en = do_swap; + end + else begin + if ((current_state__1 == STATE_DONE)) begin + req_rdy = 0; + resp_val = 1; + a_mux_sel = A_MUX_SEL_X; + a_reg_en = 0; + b_mux_sel = B_MUX_SEL_X; + b_reg_en = 0; + end + else begin + req_rdy = 0; + resp_val = 0; + a_mux_sel = A_MUX_SEL_X; + a_reg_en = 0; + b_mux_sel = B_MUX_SEL_X; + b_reg_en = 0; + end + end + end + end + + +endmodule // GcdUnitCtrlRTL_0x4d0fc71ead8d3d9e + +//----------------------------------------------------------------------------- +// RegRst_0x9f365fdf6c8998a +//----------------------------------------------------------------------------- +// dtype: 2 +// reset_value: 0 + + +module RegRst_0x9f365fdf6c8998a +( + input wire [ 0:0] clk, + input wire [ 1:0] in_, + output reg [ 1:0] out, + input wire [ 0:0] reset +); + + // localparam declarations + localparam reset_value = 0; + + + + // PYMTL SOURCE: + // + // @s.posedge_clk + // def seq_logic(): + // if s.reset: + // s.out.next = reset_value + // else: + // s.out.next = s.in_ + + // logic for seq_logic() + always @ (posedge clk) begin + if (reset) begin + out <= reset_value; + end + else begin + out <= in_; + end + end + + +endmodule // RegRst_0x9f365fdf6c8998a + +//----------------------------------------------------------------------------- +// GcdUnitDpathRTL_0x4d0fc71ead8d3d9e +//----------------------------------------------------------------------------- + + +module GcdUnitDpathRTL_0x4d0fc71ead8d3d9e +( + input wire [ 1:0] a_mux_sel, + input wire [ 0:0] a_reg_en, + input wire [ 0:0] b_mux_sel, + input wire [ 0:0] b_reg_en, + input wire [ 0:0] clk, + output wire [ 0:0] is_a_lt_b, + output wire [ 0:0] is_b_zero, + input wire [ 15:0] req_msg_a, + input wire [ 15:0] req_msg_b, + input wire [ 0:0] reset, + output wire [ 15:0] resp_msg +); + + // wire declarations + wire [ 15:0] sub_out; + wire [ 15:0] b_reg_out; + + + // a_reg temporaries + wire [ 0:0] a_reg$reset; + wire [ 15:0] a_reg$in_; + wire [ 0:0] a_reg$clk; + wire [ 0:0] a_reg$en; + wire [ 15:0] a_reg$out; + + RegEn_0x68db79c4ec1d6e5b a_reg + ( + .reset ( a_reg$reset ), + .in_ ( a_reg$in_ ), + .clk ( a_reg$clk ), + .en ( a_reg$en ), + .out ( a_reg$out ) + ); + + // a_lt_b temporaries + wire [ 0:0] a_lt_b$reset; + wire [ 0:0] a_lt_b$clk; + wire [ 15:0] a_lt_b$in0; + wire [ 15:0] a_lt_b$in1; + wire [ 0:0] a_lt_b$out; + + LtComparator_0x422b1f52edd46a85 a_lt_b + ( + .reset ( a_lt_b$reset ), + .clk ( a_lt_b$clk ), + .in0 ( a_lt_b$in0 ), + .in1 ( a_lt_b$in1 ), + .out ( a_lt_b$out ) + ); + + // b_zero temporaries + wire [ 0:0] b_zero$reset; + wire [ 15:0] b_zero$in_; + wire [ 0:0] b_zero$clk; + wire [ 0:0] b_zero$out; + + ZeroComparator_0x422b1f52edd46a85 b_zero + ( + .reset ( b_zero$reset ), + .in_ ( b_zero$in_ ), + .clk ( b_zero$clk ), + .out ( b_zero$out ) + ); + + // a_mux temporaries + wire [ 0:0] a_mux$reset; + wire [ 15:0] a_mux$in_$000; + wire [ 15:0] a_mux$in_$001; + wire [ 15:0] a_mux$in_$002; + wire [ 0:0] a_mux$clk; + wire [ 1:0] a_mux$sel; + wire [ 15:0] a_mux$out; + + Mux_0x683fa1a418b072c9 a_mux + ( + .reset ( a_mux$reset ), + .in_$000 ( a_mux$in_$000 ), + .in_$001 ( a_mux$in_$001 ), + .in_$002 ( a_mux$in_$002 ), + .clk ( a_mux$clk ), + .sel ( a_mux$sel ), + .out ( a_mux$out ) + ); + + // b_mux temporaries + wire [ 0:0] b_mux$reset; + wire [ 15:0] b_mux$in_$000; + wire [ 15:0] b_mux$in_$001; + wire [ 0:0] b_mux$clk; + wire [ 0:0] b_mux$sel; + wire [ 15:0] b_mux$out; + + Mux_0xdd6473406d1a99a b_mux + ( + .reset ( b_mux$reset ), + .in_$000 ( b_mux$in_$000 ), + .in_$001 ( b_mux$in_$001 ), + .clk ( b_mux$clk ), + .sel ( b_mux$sel ), + .out ( b_mux$out ) + ); + + // sub temporaries + wire [ 0:0] sub$reset; + wire [ 0:0] sub$clk; + wire [ 15:0] sub$in0; + wire [ 15:0] sub$in1; + wire [ 15:0] sub$out; + + Subtractor_0x422b1f52edd46a85 sub + ( + .reset ( sub$reset ), + .clk ( sub$clk ), + .in0 ( sub$in0 ), + .in1 ( sub$in1 ), + .out ( sub$out ) + ); + + // b_reg temporaries + wire [ 0:0] b_reg$reset; + wire [ 15:0] b_reg$in_; + wire [ 0:0] b_reg$clk; + wire [ 0:0] b_reg$en; + wire [ 15:0] b_reg$out; + + RegEn_0x68db79c4ec1d6e5b b_reg + ( + .reset ( b_reg$reset ), + .in_ ( b_reg$in_ ), + .clk ( b_reg$clk ), + .en ( b_reg$en ), + .out ( b_reg$out ) + ); + + // signal connections + assign a_lt_b$clk = clk; + assign a_lt_b$in0 = a_reg$out; + assign a_lt_b$in1 = b_reg$out; + assign a_lt_b$reset = reset; + assign a_mux$clk = clk; + assign a_mux$in_$000 = req_msg_a; + assign a_mux$in_$001 = sub_out; + assign a_mux$in_$002 = b_reg_out; + assign a_mux$reset = reset; + assign a_mux$sel = a_mux_sel; + assign a_reg$clk = clk; + assign a_reg$en = a_reg_en; + assign a_reg$in_ = a_mux$out; + assign a_reg$reset = reset; + assign b_mux$clk = clk; + assign b_mux$in_$000 = a_reg$out; + assign b_mux$in_$001 = req_msg_b; + assign b_mux$reset = reset; + assign b_mux$sel = b_mux_sel; + assign b_reg$clk = clk; + assign b_reg$en = b_reg_en; + assign b_reg$in_ = b_mux$out; + assign b_reg$reset = reset; + assign b_reg_out = b_reg$out; + assign b_zero$clk = clk; + assign b_zero$in_ = b_reg$out; + assign b_zero$reset = reset; + assign is_a_lt_b = a_lt_b$out; + assign is_b_zero = b_zero$out; + assign resp_msg = sub$out; + assign sub$clk = clk; + assign sub$in0 = a_reg$out; + assign sub$in1 = b_reg$out; + assign sub$reset = reset; + assign sub_out = sub$out; + + + +endmodule // GcdUnitDpathRTL_0x4d0fc71ead8d3d9e + +//----------------------------------------------------------------------------- +// RegEn_0x68db79c4ec1d6e5b +//----------------------------------------------------------------------------- +// dtype: 16 + + +module RegEn_0x68db79c4ec1d6e5b +( + input wire [ 0:0] clk, + input wire [ 0:0] en, + input wire [ 15:0] in_, + output reg [ 15:0] out, + input wire [ 0:0] reset +); + + + + // PYMTL SOURCE: + // + // @s.posedge_clk + // def seq_logic(): + // if s.en: + // s.out.next = s.in_ + + // logic for seq_logic() + always @ (posedge clk) begin + if (en) begin + out <= in_; + end + else begin + end + end + + +endmodule // RegEn_0x68db79c4ec1d6e5b + +//----------------------------------------------------------------------------- +// LtComparator_0x422b1f52edd46a85 +//----------------------------------------------------------------------------- +// nbits: 16 + + +module LtComparator_0x422b1f52edd46a85 +( + input wire [ 0:0] clk, + input wire [ 15:0] in0, + input wire [ 15:0] in1, + output reg [ 0:0] out, + input wire [ 0:0] reset +); + + + + // PYMTL SOURCE: + // + // @s.combinational + // def comb_logic(): + // s.out.value = s.in0 < s.in1 + + // logic for comb_logic() + always @ (*) begin + out = (in0 < in1); + end + + +endmodule // LtComparator_0x422b1f52edd46a85 + +//----------------------------------------------------------------------------- +// ZeroComparator_0x422b1f52edd46a85 +//----------------------------------------------------------------------------- +// nbits: 16 + + +module ZeroComparator_0x422b1f52edd46a85 +( + input wire [ 0:0] clk, + input wire [ 15:0] in_, + output reg [ 0:0] out, + input wire [ 0:0] reset +); + + + + // PYMTL SOURCE: + // + // @s.combinational + // def comb_logic(): + // s.out.value = s.in_ == 0 + + // logic for comb_logic() + always @ (*) begin + out = (in_ == 0); + end + + +endmodule // ZeroComparator_0x422b1f52edd46a85 + +//----------------------------------------------------------------------------- +// Mux_0x683fa1a418b072c9 +//----------------------------------------------------------------------------- +// dtype: 16 +// nports: 3 + + +module Mux_0x683fa1a418b072c9 +( + input wire [ 0:0] clk, + input wire [ 15:0] in_$000, + input wire [ 15:0] in_$001, + input wire [ 15:0] in_$002, + output reg [ 15:0] out, + input wire [ 0:0] reset, + input wire [ 1:0] sel +); + + // localparam declarations + localparam nports = 3; + + + // array declarations + wire [ 15:0] in_[0:2]; + assign in_[ 0] = in_$000; + assign in_[ 1] = in_$001; + assign in_[ 2] = in_$002; + + // PYMTL SOURCE: + // + // @s.combinational + // def comb_logic(): + // assert s.sel < nports + // s.out.v = s.in_[ s.sel ] + + // logic for comb_logic() + always @ (*) begin + out = in_[sel]; + end + + +endmodule // Mux_0x683fa1a418b072c9 + +//----------------------------------------------------------------------------- +// Mux_0xdd6473406d1a99a +//----------------------------------------------------------------------------- +// dtype: 16 +// nports: 2 + + +module Mux_0xdd6473406d1a99a +( + input wire [ 0:0] clk, + input wire [ 15:0] in_$000, + input wire [ 15:0] in_$001, + output reg [ 15:0] out, + input wire [ 0:0] reset, + input wire [ 0:0] sel +); + + // localparam declarations + localparam nports = 2; + + + // array declarations + wire [ 15:0] in_[0:1]; + assign in_[ 0] = in_$000; + assign in_[ 1] = in_$001; + + // PYMTL SOURCE: + // + // @s.combinational + // def comb_logic(): + // assert s.sel < nports + // s.out.v = s.in_[ s.sel ] + + // logic for comb_logic() + always @ (*) begin + out = in_[sel]; + end + + +endmodule // Mux_0xdd6473406d1a99a + +//----------------------------------------------------------------------------- +// Subtractor_0x422b1f52edd46a85 +//----------------------------------------------------------------------------- +// nbits: 16 + + +module Subtractor_0x422b1f52edd46a85 +( + input wire [ 0:0] clk, + input wire [ 15:0] in0, + input wire [ 15:0] in1, + output reg [ 15:0] out, + input wire [ 0:0] reset +); + + + + // PYMTL SOURCE: + // + // @s.combinational + // def comb_logic(): + // s.out.value = s.in0 - s.in1 + + // logic for comb_logic() + always @ (*) begin + out = (in0-in1); + end + + +endmodule // Subtractor_0x422b1f52edd46a85 + diff --git a/examples/saif_example/saif_trace.cpp b/examples/saif_example/saif_trace.cpp index 19c335cd3..c37ea8000 100644 --- a/examples/saif_example/saif_trace.cpp +++ b/examples/saif_example/saif_trace.cpp @@ -11,7 +11,7 @@ #include -#include "Vcounter.h" +#include "Vgcd.h" int errors = 0; @@ -29,11 +29,11 @@ int main(int argc, char** argv) { Verilated::traceEverOn(true); Verilated::commandArgs(argc, argv); - std::unique_ptr top{new Vcounter}; + std::unique_ptr top{new Vgcd}; std::unique_ptr tfp{new VerilatedSaifC}; - static constexpr int SIMULATION_DURATION{199}; + static constexpr int SIMULATION_DURATION{10000}; top->trace(tfp.get(), SIMULATION_DURATION); tfp->open(trace_name()); @@ -42,14 +42,21 @@ int main(int argc, char** argv) { while (main_time < SIMULATION_DURATION) { top->clk = !top->clk; + top->req_msg = rand() & 0xffffffff; + top->req_val = rand() & 0x1; + top->reset = rand() & 0x1; + top->resp_rdy = rand() & 0x1; + top->eval(); tfp->dump(static_cast(main_time)); ++main_time; } + tfp->close(); top->final(); tfp.reset(); top.reset(); printf("*-* All Finished *-*\n"); + return errors; } diff --git a/examples/saif_example/saif_trace_example/config.mk b/examples/saif_example/saif_trace_example/config.mk index 2bbca0b93..98919a1d1 100644 --- a/examples/saif_example/saif_trace_example/config.mk +++ b/examples/saif_example/saif_trace_example/config.mk @@ -1,7 +1,7 @@ export PLATFORM = asap7 export DESIGN_NICKNAME = saif_trace_example -export DESIGN_NAME = t +export DESIGN_NAME = gcd export VERILOG_FILES = $(sort $(wildcard $(DESIGN_HOME)/src/$(DESIGN_NICKNAME)/*.v)) export SDC_FILE = $(DESIGN_HOME)/$(PLATFORM)/$(DESIGN_NICKNAME)/constraint.sdc diff --git a/examples/saif_example/src/saif_trace_example/counter.v b/examples/saif_example/src/saif_trace_example/counter.v deleted file mode 100644 index 9cf1356cd..000000000 --- a/examples/saif_example/src/saif_trace_example/counter.v +++ /dev/null @@ -1,51 +0,0 @@ -// DESCRIPTION: Verilator: Verilog Test module -// -// Copyright 2025 by Antmicro. This program is free software; you can -// redistribute it and/or modify it under the terms of either the GNU -// Lesser General Public License Version 3 or the Perl Artistic License -// Version 2.0. -// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 - -module t ( - // Outputs - state, - // Inputs - clk); - - input clk; - reg rst; - output [7:0] state; - - counter c0 ( - .clk (clk), - .rst (rst), - .out (state)); - - int cyc; - - always @ (posedge clk) begin - cyc <= cyc + 1; - if (cyc == 0) begin - rst <= 1; - end - else if (cyc == 10) begin - rst <= 0; - end - else if (cyc == 11) begin - rst <= 1; - end - end -endmodule - -module counter ( - input clk, - input rst, - output reg[7:0] out); - - always @ (posedge clk) begin - if (!rst) - out <= 0; - else - out <= out + 1; - end -endmodule diff --git a/examples/saif_example/src/saif_trace_example/gcd.v b/examples/saif_example/src/saif_trace_example/gcd.v new file mode 100644 index 000000000..cca5856b3 --- /dev/null +++ b/examples/saif_example/src/saif_trace_example/gcd.v @@ -0,0 +1,755 @@ +//----------------------------------------------------------------------------- +// GcdUnit +//----------------------------------------------------------------------------- +// +// Originally Generated from PyMTL with a few modifications to make it more +// friendly to OpenROAD tools + +//module GcdUnit +module gcd +( + input wire clk, + input wire [ 31:0] req_msg, + output wire req_rdy, + input wire req_val, + input wire reset, + output wire [ 15:0] resp_msg, + input wire resp_rdy, + output wire resp_val +); + + // ctrl temporaries + wire [ 0:0] ctrl$is_b_zero; + wire [ 0:0] ctrl$resp_rdy; + wire [ 0:0] ctrl$clk; + wire [ 0:0] ctrl$is_a_lt_b; + wire [ 0:0] ctrl$req_val; + wire [ 0:0] ctrl$reset; + wire [ 1:0] ctrl$a_mux_sel; + wire [ 0:0] ctrl$resp_val; + wire [ 0:0] ctrl$b_mux_sel; + wire [ 0:0] ctrl$b_reg_en; + wire [ 0:0] ctrl$a_reg_en; + wire [ 0:0] ctrl$req_rdy; + + GcdUnitCtrlRTL_0x4d0fc71ead8d3d9e ctrl + ( + .is_b_zero ( ctrl$is_b_zero ), + .resp_rdy ( ctrl$resp_rdy ), + .clk ( ctrl$clk ), + .is_a_lt_b ( ctrl$is_a_lt_b ), + .req_val ( ctrl$req_val ), + .reset ( ctrl$reset ), + .a_mux_sel ( ctrl$a_mux_sel ), + .resp_val ( ctrl$resp_val ), + .b_mux_sel ( ctrl$b_mux_sel ), + .b_reg_en ( ctrl$b_reg_en ), + .a_reg_en ( ctrl$a_reg_en ), + .req_rdy ( ctrl$req_rdy ) + ); + + // dpath temporaries + wire [ 1:0] dpath$a_mux_sel; + wire [ 0:0] dpath$clk; + wire [ 15:0] dpath$req_msg_b; + wire [ 15:0] dpath$req_msg_a; + wire [ 0:0] dpath$b_mux_sel; + wire [ 0:0] dpath$reset; + wire [ 0:0] dpath$b_reg_en; + wire [ 0:0] dpath$a_reg_en; + wire [ 0:0] dpath$is_b_zero; + wire [ 15:0] dpath$resp_msg; + wire [ 0:0] dpath$is_a_lt_b; + + GcdUnitDpathRTL_0x4d0fc71ead8d3d9e dpath + ( + .a_mux_sel ( dpath$a_mux_sel ), + .clk ( dpath$clk ), + .req_msg_b ( dpath$req_msg_b ), + .req_msg_a ( dpath$req_msg_a ), + .b_mux_sel ( dpath$b_mux_sel ), + .reset ( dpath$reset ), + .b_reg_en ( dpath$b_reg_en ), + .a_reg_en ( dpath$a_reg_en ), + .is_b_zero ( dpath$is_b_zero ), + .resp_msg ( dpath$resp_msg ), + .is_a_lt_b ( dpath$is_a_lt_b ) + ); + + // signal connections + assign ctrl$clk = clk; + assign ctrl$is_a_lt_b = dpath$is_a_lt_b; + assign ctrl$is_b_zero = dpath$is_b_zero; + assign ctrl$req_val = req_val; + assign ctrl$reset = reset; + assign ctrl$resp_rdy = resp_rdy; + assign dpath$a_mux_sel = ctrl$a_mux_sel; + assign dpath$a_reg_en = ctrl$a_reg_en; + assign dpath$b_mux_sel = ctrl$b_mux_sel; + assign dpath$b_reg_en = ctrl$b_reg_en; + assign dpath$clk = clk; + assign dpath$req_msg_a = req_msg[31:16]; + assign dpath$req_msg_b = req_msg[15:0]; + assign dpath$reset = reset; + assign req_rdy = ctrl$req_rdy; + assign resp_msg = dpath$resp_msg; + assign resp_val = ctrl$resp_val; + + + +endmodule // GcdUnit + +//----------------------------------------------------------------------------- +// GcdUnitCtrlRTL_0x4d0fc71ead8d3d9e +//----------------------------------------------------------------------------- + + +module GcdUnitCtrlRTL_0x4d0fc71ead8d3d9e +( + output reg [ 1:0] a_mux_sel, + output reg [ 0:0] a_reg_en, + output reg [ 0:0] b_mux_sel, + output reg [ 0:0] b_reg_en, + input wire [ 0:0] clk, + input wire [ 0:0] is_a_lt_b, + input wire [ 0:0] is_b_zero, + output reg [ 0:0] req_rdy, + input wire [ 0:0] req_val, + input wire [ 0:0] reset, + input wire [ 0:0] resp_rdy, + output reg [ 0:0] resp_val +); + + // register declarations + reg [ 1:0] curr_state__0; + reg [ 1:0] current_state__1; + reg [ 0:0] do_sub; + reg [ 0:0] do_swap; + reg [ 1:0] next_state__0; + reg [ 1:0] state$in_; + + // localparam declarations + localparam A_MUX_SEL_B = 2; + localparam A_MUX_SEL_IN = 0; + localparam A_MUX_SEL_SUB = 1; + localparam A_MUX_SEL_X = 0; + localparam B_MUX_SEL_A = 0; + localparam B_MUX_SEL_IN = 1; + localparam B_MUX_SEL_X = 0; + localparam STATE_CALC = 1; + localparam STATE_DONE = 2; + localparam STATE_IDLE = 0; + + // state temporaries + wire [ 0:0] state$reset; + wire [ 0:0] state$clk; + wire [ 1:0] state$out; + + RegRst_0x9f365fdf6c8998a state + ( + .reset ( state$reset ), + .in_ ( state$in_ ), + .clk ( state$clk ), + .out ( state$out ) + ); + + // signal connections + assign state$clk = clk; + assign state$reset = reset; + + + // PYMTL SOURCE: + // + // @s.combinational + // def state_transitions(): + // + // curr_state = s.state.out + // next_state = s.state.out + // + // # Transistions out of IDLE state + // + // if ( curr_state == s.STATE_IDLE ): + // if ( s.req_val and s.req_rdy ): + // next_state = s.STATE_CALC + // + // # Transistions out of CALC state + // + // if ( curr_state == s.STATE_CALC ): + // if ( not s.is_a_lt_b and s.is_b_zero ): + // next_state = s.STATE_DONE + // + // # Transistions out of DONE state + // + // if ( curr_state == s.STATE_DONE ): + // if ( s.resp_val and s.resp_rdy ): + // next_state = s.STATE_IDLE + // + // s.state.in_.value = next_state + + // logic for state_transitions() + always @ (*) begin + curr_state__0 = state$out; + next_state__0 = state$out; + if ((curr_state__0 == STATE_IDLE)) begin + if ((req_val&&req_rdy)) begin + next_state__0 = STATE_CALC; + end + else begin + end + end + else begin + end + if ((curr_state__0 == STATE_CALC)) begin + if ((!is_a_lt_b&&is_b_zero)) begin + next_state__0 = STATE_DONE; + end + else begin + end + end + else begin + end + if ((curr_state__0 == STATE_DONE)) begin + if ((resp_val&&resp_rdy)) begin + next_state__0 = STATE_IDLE; + end + else begin + end + end + else begin + end + state$in_ = next_state__0; + end + + // PYMTL SOURCE: + // + // @s.combinational + // def state_outputs(): + // + // current_state = s.state.out + // + // # In IDLE state we simply wait for inputs to arrive and latch them + // + // if current_state == s.STATE_IDLE: + // s.req_rdy.value = 1 + // s.resp_val.value = 0 + // s.a_mux_sel.value = A_MUX_SEL_IN + // s.a_reg_en.value = 1 + // s.b_mux_sel.value = B_MUX_SEL_IN + // s.b_reg_en.value = 1 + // + // # In CALC state we iteratively swap/sub to calculate GCD + // + // elif current_state == s.STATE_CALC: + // + // s.do_swap.value = s.is_a_lt_b + // s.do_sub.value = ~s.is_b_zero + // + // s.req_rdy.value = 0 + // s.resp_val.value = 0 + // s.a_mux_sel.value = A_MUX_SEL_B if s.do_swap else A_MUX_SEL_SUB + // s.a_reg_en.value = 1 + // s.b_mux_sel.value = B_MUX_SEL_A + // s.b_reg_en.value = s.do_swap + // + // # In DONE state we simply wait for output transaction to occur + // + // elif current_state == s.STATE_DONE: + // s.req_rdy.value = 0 + // s.resp_val.value = 1 + // s.a_mux_sel.value = A_MUX_SEL_X + // s.a_reg_en.value = 0 + // s.b_mux_sel.value = B_MUX_SEL_X + // s.b_reg_en.value = 0 + // + // # Default case that we should not hit + // + // else: + // s.req_rdy.value = 0 + // s.resp_val.value = 0 + // s.a_mux_sel.value = A_MUX_SEL_X + // s.a_reg_en.value = 0 + // s.b_mux_sel.value = B_MUX_SEL_X + // s.b_reg_en.value = 0 + + // logic for state_outputs() + always @ (*) begin + current_state__1 = state$out; + if ((current_state__1 == STATE_IDLE)) begin + req_rdy = 1; + resp_val = 0; + a_mux_sel = A_MUX_SEL_IN; + a_reg_en = 1; + b_mux_sel = B_MUX_SEL_IN; + b_reg_en = 1; + end + else begin + if ((current_state__1 == STATE_CALC)) begin + do_swap = is_a_lt_b; + do_sub = ~is_b_zero; + req_rdy = 0; + resp_val = 0; + a_mux_sel = do_swap ? A_MUX_SEL_B : A_MUX_SEL_SUB; + a_reg_en = 1; + b_mux_sel = B_MUX_SEL_A; + b_reg_en = do_swap; + end + else begin + if ((current_state__1 == STATE_DONE)) begin + req_rdy = 0; + resp_val = 1; + a_mux_sel = A_MUX_SEL_X; + a_reg_en = 0; + b_mux_sel = B_MUX_SEL_X; + b_reg_en = 0; + end + else begin + req_rdy = 0; + resp_val = 0; + a_mux_sel = A_MUX_SEL_X; + a_reg_en = 0; + b_mux_sel = B_MUX_SEL_X; + b_reg_en = 0; + end + end + end + end + + +endmodule // GcdUnitCtrlRTL_0x4d0fc71ead8d3d9e + +//----------------------------------------------------------------------------- +// RegRst_0x9f365fdf6c8998a +//----------------------------------------------------------------------------- +// dtype: 2 +// reset_value: 0 + + +module RegRst_0x9f365fdf6c8998a +( + input wire [ 0:0] clk, + input wire [ 1:0] in_, + output reg [ 1:0] out, + input wire [ 0:0] reset +); + + // localparam declarations + localparam reset_value = 0; + + + + // PYMTL SOURCE: + // + // @s.posedge_clk + // def seq_logic(): + // if s.reset: + // s.out.next = reset_value + // else: + // s.out.next = s.in_ + + // logic for seq_logic() + always @ (posedge clk) begin + if (reset) begin + out <= reset_value; + end + else begin + out <= in_; + end + end + + +endmodule // RegRst_0x9f365fdf6c8998a + +//----------------------------------------------------------------------------- +// GcdUnitDpathRTL_0x4d0fc71ead8d3d9e +//----------------------------------------------------------------------------- + + +module GcdUnitDpathRTL_0x4d0fc71ead8d3d9e +( + input wire [ 1:0] a_mux_sel, + input wire [ 0:0] a_reg_en, + input wire [ 0:0] b_mux_sel, + input wire [ 0:0] b_reg_en, + input wire [ 0:0] clk, + output wire [ 0:0] is_a_lt_b, + output wire [ 0:0] is_b_zero, + input wire [ 15:0] req_msg_a, + input wire [ 15:0] req_msg_b, + input wire [ 0:0] reset, + output wire [ 15:0] resp_msg +); + + // wire declarations + wire [ 15:0] sub_out; + wire [ 15:0] b_reg_out; + + + // a_reg temporaries + wire [ 0:0] a_reg$reset; + wire [ 15:0] a_reg$in_; + wire [ 0:0] a_reg$clk; + wire [ 0:0] a_reg$en; + wire [ 15:0] a_reg$out; + + RegEn_0x68db79c4ec1d6e5b a_reg + ( + .reset ( a_reg$reset ), + .in_ ( a_reg$in_ ), + .clk ( a_reg$clk ), + .en ( a_reg$en ), + .out ( a_reg$out ) + ); + + // a_lt_b temporaries + wire [ 0:0] a_lt_b$reset; + wire [ 0:0] a_lt_b$clk; + wire [ 15:0] a_lt_b$in0; + wire [ 15:0] a_lt_b$in1; + wire [ 0:0] a_lt_b$out; + + LtComparator_0x422b1f52edd46a85 a_lt_b + ( + .reset ( a_lt_b$reset ), + .clk ( a_lt_b$clk ), + .in0 ( a_lt_b$in0 ), + .in1 ( a_lt_b$in1 ), + .out ( a_lt_b$out ) + ); + + // b_zero temporaries + wire [ 0:0] b_zero$reset; + wire [ 15:0] b_zero$in_; + wire [ 0:0] b_zero$clk; + wire [ 0:0] b_zero$out; + + ZeroComparator_0x422b1f52edd46a85 b_zero + ( + .reset ( b_zero$reset ), + .in_ ( b_zero$in_ ), + .clk ( b_zero$clk ), + .out ( b_zero$out ) + ); + + // a_mux temporaries + wire [ 0:0] a_mux$reset; + wire [ 15:0] a_mux$in_$000; + wire [ 15:0] a_mux$in_$001; + wire [ 15:0] a_mux$in_$002; + wire [ 0:0] a_mux$clk; + wire [ 1:0] a_mux$sel; + wire [ 15:0] a_mux$out; + + Mux_0x683fa1a418b072c9 a_mux + ( + .reset ( a_mux$reset ), + .in_$000 ( a_mux$in_$000 ), + .in_$001 ( a_mux$in_$001 ), + .in_$002 ( a_mux$in_$002 ), + .clk ( a_mux$clk ), + .sel ( a_mux$sel ), + .out ( a_mux$out ) + ); + + // b_mux temporaries + wire [ 0:0] b_mux$reset; + wire [ 15:0] b_mux$in_$000; + wire [ 15:0] b_mux$in_$001; + wire [ 0:0] b_mux$clk; + wire [ 0:0] b_mux$sel; + wire [ 15:0] b_mux$out; + + Mux_0xdd6473406d1a99a b_mux + ( + .reset ( b_mux$reset ), + .in_$000 ( b_mux$in_$000 ), + .in_$001 ( b_mux$in_$001 ), + .clk ( b_mux$clk ), + .sel ( b_mux$sel ), + .out ( b_mux$out ) + ); + + // sub temporaries + wire [ 0:0] sub$reset; + wire [ 0:0] sub$clk; + wire [ 15:0] sub$in0; + wire [ 15:0] sub$in1; + wire [ 15:0] sub$out; + + Subtractor_0x422b1f52edd46a85 sub + ( + .reset ( sub$reset ), + .clk ( sub$clk ), + .in0 ( sub$in0 ), + .in1 ( sub$in1 ), + .out ( sub$out ) + ); + + // b_reg temporaries + wire [ 0:0] b_reg$reset; + wire [ 15:0] b_reg$in_; + wire [ 0:0] b_reg$clk; + wire [ 0:0] b_reg$en; + wire [ 15:0] b_reg$out; + + RegEn_0x68db79c4ec1d6e5b b_reg + ( + .reset ( b_reg$reset ), + .in_ ( b_reg$in_ ), + .clk ( b_reg$clk ), + .en ( b_reg$en ), + .out ( b_reg$out ) + ); + + // signal connections + assign a_lt_b$clk = clk; + assign a_lt_b$in0 = a_reg$out; + assign a_lt_b$in1 = b_reg$out; + assign a_lt_b$reset = reset; + assign a_mux$clk = clk; + assign a_mux$in_$000 = req_msg_a; + assign a_mux$in_$001 = sub_out; + assign a_mux$in_$002 = b_reg_out; + assign a_mux$reset = reset; + assign a_mux$sel = a_mux_sel; + assign a_reg$clk = clk; + assign a_reg$en = a_reg_en; + assign a_reg$in_ = a_mux$out; + assign a_reg$reset = reset; + assign b_mux$clk = clk; + assign b_mux$in_$000 = a_reg$out; + assign b_mux$in_$001 = req_msg_b; + assign b_mux$reset = reset; + assign b_mux$sel = b_mux_sel; + assign b_reg$clk = clk; + assign b_reg$en = b_reg_en; + assign b_reg$in_ = b_mux$out; + assign b_reg$reset = reset; + assign b_reg_out = b_reg$out; + assign b_zero$clk = clk; + assign b_zero$in_ = b_reg$out; + assign b_zero$reset = reset; + assign is_a_lt_b = a_lt_b$out; + assign is_b_zero = b_zero$out; + assign resp_msg = sub$out; + assign sub$clk = clk; + assign sub$in0 = a_reg$out; + assign sub$in1 = b_reg$out; + assign sub$reset = reset; + assign sub_out = sub$out; + + + +endmodule // GcdUnitDpathRTL_0x4d0fc71ead8d3d9e + +//----------------------------------------------------------------------------- +// RegEn_0x68db79c4ec1d6e5b +//----------------------------------------------------------------------------- +// dtype: 16 + + +module RegEn_0x68db79c4ec1d6e5b +( + input wire [ 0:0] clk, + input wire [ 0:0] en, + input wire [ 15:0] in_, + output reg [ 15:0] out, + input wire [ 0:0] reset +); + + + + // PYMTL SOURCE: + // + // @s.posedge_clk + // def seq_logic(): + // if s.en: + // s.out.next = s.in_ + + // logic for seq_logic() + always @ (posedge clk) begin + if (en) begin + out <= in_; + end + else begin + end + end + + +endmodule // RegEn_0x68db79c4ec1d6e5b + +//----------------------------------------------------------------------------- +// LtComparator_0x422b1f52edd46a85 +//----------------------------------------------------------------------------- +// nbits: 16 + + +module LtComparator_0x422b1f52edd46a85 +( + input wire [ 0:0] clk, + input wire [ 15:0] in0, + input wire [ 15:0] in1, + output reg [ 0:0] out, + input wire [ 0:0] reset +); + + + + // PYMTL SOURCE: + // + // @s.combinational + // def comb_logic(): + // s.out.value = s.in0 < s.in1 + + // logic for comb_logic() + always @ (*) begin + out = (in0 < in1); + end + + +endmodule // LtComparator_0x422b1f52edd46a85 + +//----------------------------------------------------------------------------- +// ZeroComparator_0x422b1f52edd46a85 +//----------------------------------------------------------------------------- +// nbits: 16 + + +module ZeroComparator_0x422b1f52edd46a85 +( + input wire [ 0:0] clk, + input wire [ 15:0] in_, + output reg [ 0:0] out, + input wire [ 0:0] reset +); + + + + // PYMTL SOURCE: + // + // @s.combinational + // def comb_logic(): + // s.out.value = s.in_ == 0 + + // logic for comb_logic() + always @ (*) begin + out = (in_ == 0); + end + + +endmodule // ZeroComparator_0x422b1f52edd46a85 + +//----------------------------------------------------------------------------- +// Mux_0x683fa1a418b072c9 +//----------------------------------------------------------------------------- +// dtype: 16 +// nports: 3 + + +module Mux_0x683fa1a418b072c9 +( + input wire [ 0:0] clk, + input wire [ 15:0] in_$000, + input wire [ 15:0] in_$001, + input wire [ 15:0] in_$002, + output reg [ 15:0] out, + input wire [ 0:0] reset, + input wire [ 1:0] sel +); + + // localparam declarations + localparam nports = 3; + + + // array declarations + wire [ 15:0] in_[0:2]; + assign in_[ 0] = in_$000; + assign in_[ 1] = in_$001; + assign in_[ 2] = in_$002; + + // PYMTL SOURCE: + // + // @s.combinational + // def comb_logic(): + // assert s.sel < nports + // s.out.v = s.in_[ s.sel ] + + // logic for comb_logic() + always @ (*) begin + out = in_[sel]; + end + + +endmodule // Mux_0x683fa1a418b072c9 + +//----------------------------------------------------------------------------- +// Mux_0xdd6473406d1a99a +//----------------------------------------------------------------------------- +// dtype: 16 +// nports: 2 + + +module Mux_0xdd6473406d1a99a +( + input wire [ 0:0] clk, + input wire [ 15:0] in_$000, + input wire [ 15:0] in_$001, + output reg [ 15:0] out, + input wire [ 0:0] reset, + input wire [ 0:0] sel +); + + // localparam declarations + localparam nports = 2; + + + // array declarations + wire [ 15:0] in_[0:1]; + assign in_[ 0] = in_$000; + assign in_[ 1] = in_$001; + + // PYMTL SOURCE: + // + // @s.combinational + // def comb_logic(): + // assert s.sel < nports + // s.out.v = s.in_[ s.sel ] + + // logic for comb_logic() + always @ (*) begin + out = in_[sel]; + end + + +endmodule // Mux_0xdd6473406d1a99a + +//----------------------------------------------------------------------------- +// Subtractor_0x422b1f52edd46a85 +//----------------------------------------------------------------------------- +// nbits: 16 + + +module Subtractor_0x422b1f52edd46a85 +( + input wire [ 0:0] clk, + input wire [ 15:0] in0, + input wire [ 15:0] in1, + output reg [ 15:0] out, + input wire [ 0:0] reset +); + + + + // PYMTL SOURCE: + // + // @s.combinational + // def comb_logic(): + // s.out.value = s.in0 - s.in1 + + // logic for comb_logic() + always @ (*) begin + out = (in0-in1); + end + + +endmodule // Subtractor_0x422b1f52edd46a85 +