- BlackBox: name: Clash.Signal.Internal.delay# kind: Declaration outputUsage: NonBlocking type: |- delay# :: ( KnownDomain dom -- ARG[0] , Undefined a ) -- ARG[1] => Clock dom -- ARG[2] -> Enable dom -- ARG[3] -> a -- ARG[4] -> Signal clk a -- ARG[5] -> Signal clk a resultInit: template: ~IF~ISINITDEFINED[0]~THEN~CONST[4]~ELSE~FI resultName: template: ~CTXNAME template: |- // delay begin~IF ~ISACTIVEENABLE[3] ~THEN always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[2]) begin : ~GENSYM[~RESULT_delay][1] if (~ARG[3]) begin ~RESULT <= ~ARG[5]; end end~ELSE always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[2]) begin : ~SYM[1] ~RESULT <= ~ARG[5]; end~FI // delay end - BlackBox: name: Clash.Signal.Internal.asyncRegister# kind: Declaration outputUsage: NonBlocking type: |- asyncRegister# :: ( KnownDomain dom -- ARG[0] , NFDataX a ) -- ARG[1] => Clock dom -- ARG[2] -> Reset dom -- ARG[3] -> Enable dom -- ARG[4] -> a -- ARG[5] (powerup value) -> a -- ARG[6] (reset value) -> Signal clk a -- ARG[7] -> Signal clk a resultInit: template: ~IF~ISINITDEFINED[0]~THEN~CONST[5]~ELSE~FI resultName: template: ~CTXNAME template: |- // async register begin always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[2]~IF ~ISUNDEFINED[6] ~THEN ~ELSE or ~IF ~ISACTIVEHIGH[0] ~THEN posedge ~ELSE negedge ~FI ~VAR[rst][3]~FI) begin : ~GENSYM[~RESULT_register][1] ~IF ~ISUNDEFINED[6] ~THEN ~ELSEif (~IF ~ISACTIVEHIGH[0] ~THEN ~ELSE ! ~FI~VAR[rst][3]) begin ~RESULT <= ~CONST[6]; end else ~FI~IF ~ISACTIVEENABLE[4] ~THENif (~ARG[4]) ~ELSE~FIbegin ~RESULT <= ~ARG[7]; end end // async register end - BlackBox: name: Clash.Signal.Internal.register# kind: Declaration outputUsage: NonBlocking type: |- register# :: ( KnownDomain dom -- ARG[0] , Undefined a ) -- ARG[1] => Clock dom -- ARG[2] -> Reset dom -- ARG[3] -> Enable dom -- ARG[4] -> a -- ARG[5] (powerup value) -> a -- ARG[6] (reset value) -> Signal clk a -- ARG[7] -> Signal clk a resultInit: template: ~IF~ISINITDEFINED[0]~THEN~CONST[5]~ELSE~FI resultName: template: ~CTXNAME template: |- // register begin always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[2]~IF ~ISSYNC[0] ~THEN ~ELSE~IF ~ISUNDEFINED[6] ~THEN ~ELSE or ~IF ~ISACTIVEHIGH[0] ~THEN posedge ~ELSE negedge ~FI ~VAR[rst][3]~FI~FI) begin : ~GENSYM[~RESULT_register][1] ~IF ~ISUNDEFINED[6] ~THEN ~ELSEif (~IF ~ISACTIVEHIGH[0] ~THEN ~ELSE ! ~FI~VAR[rst][3]) begin ~RESULT <= ~CONST[6]; end else ~FI~IF ~ISACTIVEENABLE[4] ~THENif (~ARG[4]) ~ELSE~FIbegin ~RESULT <= ~ARG[7]; end end // register end - BlackBox: name: Clash.Signal.Internal.tbClockGen kind: Declaration type: |- tbClockGen :: KnownDomain dom -- ARG[0] => Signal dom Bool -- ARG[1] -> Clock dom template: |- // tbClockGen begin // pragma translate_off reg ~TYPO ~GENSYM[clk][0]; // 1 = 0.1ps localparam ~GENSYM[half_period][1] = (~PERIOD[0]0 / 2); always begin // Delay of 1 mitigates race conditions (https://github.com/steveicarus/iverilog/issues/160) #1 ~SYM[0] = ~IF~ACTIVEEDGE[Rising][0]~THEN 0 ~ELSE 1 ~FI; `ifndef VERILATOR #~LONGESTPERIOD0 forever begin ~IF~ISACTIVEENABLE[1]~THEN if (~ ~ARG[1]) begin $finish(0); end ~ELSE~FI ~SYM[0] = ~ ~SYM[0]; #~SYM[1]; ~SYM[0] = ~ ~SYM[0]; #~SYM[1]; end `else ~SYM[0] = $c("this->~GENSYM[tb_clock_gen][2](",~SYM[1],",~IF~ACTIVEEDGE[Rising][0]~THENtrue~ELSEfalse~FI,",(~ ~ARG[1]),")"); `endif end `ifdef VERILATOR `systemc_interface CData ~SYM[2](vluint32_t half_period, bool active_rising, bool result_rec) { static vluint32_t init_wait = ~LONGESTPERIOD0; static vluint32_t to_wait = 0; static CData clock = active_rising ? 0 : 1; if(init_wait == 0) { if(result_rec) { std::exit(0); } else { if(to_wait == 0) { to_wait = half_period - 1; clock = clock == 0 ? 1 : 0; } else { to_wait = to_wait - 1; } } } else { init_wait = init_wait - 1; } return clock; } `verilog `endif assign ~RESULT = ~SYM[0]; // pragma translate_on // tbClockGen end warning: Clash.Signal.Internal.tbClockGen is not synthesizable! workInfo: Always - BlackBox: name: Clash.Signal.Internal.tbDynamicClockGen kind: Declaration type: |- clockGen :: KnownDomain dom -- ARG[0] -> Signal dom Int64 -- ARG[1] -> Signal dom Bool -- ARG[2] => Clock dom template: |- // tbDynamicClockGen begin // pragma translate_off reg ~TYPO ~GENSYM[clk][0]; time ~GENSYM[half_period][1]; always begin // Delay of 1 mitigates race conditions (https://github.com/steveicarus/iverilog/issues/160) #1 ~SYM[0] = ~IF~ACTIVEEDGE[Rising][0]~THEN 0 ~ELSE 1 ~FI; #~LONGESTPERIOD0 forever begin ~IF~ISACTIVEENABLE[2]~THEN if (~ ~ARG[2]) begin $finish(0); end ~ELSE~FI // 1 = 0.1ps ~SYM[1] = (~VAR[periods][1] / 2); ~SYM[0] = ~ ~SYM[0]; #(~SYM[1] * 0.01); ~SYM[0] = ~ ~SYM[0]; #(~SYM[1] * 0.01); end end assign ~RESULT = ~SYM[0]; // pragma translate_on // tbDynamicClockGen end warning: Clash.Signal.Internal.tbDynamicClockGen is not synthesizable! workInfo: Always - BlackBox: name: Clash.Signal.Internal.resetGenN kind: Declaration type: 'resetGenN :: (KnownDomain dom, 1 <= n) => SNat n -> Reset dom' template: |- // resetGen begin // pragma translate_off reg ~TYPO ~GENSYM[rst][0]; localparam ~GENSYM[reset_period][1] = ~LONGESTPERIOD0 - 10 + (~LIT[2] * ~PERIOD[0]0); `ifndef VERILATOR initial begin #1 ~SYM[0] = ~IF ~ISACTIVEHIGH[0] ~THEN 1 ~ELSE 0 ~FI; #~SYM[1] ~SYM[0] = ~IF ~ISACTIVEHIGH[0] ~THEN 0 ~ELSE 1 ~FI; end `else always begin // The redundant (~SYM[0] | ~ ~SYM[0]) is needed to ensure that this is // calculated in every cycle by verilator. Without it, the reset will stop // being updated and will be stuck as asserted forever. ~SYM[0] = $c("this->~GENSYM[reset_gen][2](",~SYM[1],",~IF~ISACTIVEHIGH[0]~THENtrue~ELSEfalse~FI)") & (~SYM[0] | ~ ~SYM[0]); end `systemc_interface CData ~SYM[2](vluint32_t reset_period, bool active_high) { static vluint32_t to_wait = reset_period; static CData reset = active_high ? 1 : 0; static bool finished = false; if(!finished) { if(to_wait == 0) { reset = reset == 0 ? 1 : 0; finished = true; } else { to_wait = to_wait - 1; } } return reset; } `verilog `endif assign ~RESULT = ~SYM[0]; // pragma translate_on // resetGen end workInfo: Always