extern "math.sv" { // Fixed point square root operator, using a digit-by-digit algorithm. // en.wikipedia.org/wiki/Methods_of_computing_square_roots#Digit-by-digit_calculation primitive fp_sqrt[ WIDTH, INT_WIDTH, FRAC_WIDTH ]( @clk clk: 1, @write_together(1) @go go: 1, @write_together(1) in: WIDTH ) -> ( out: WIDTH, @done done: 1 ); primitive sqrt[ WIDTH ]( @clk clk: 1, @write_together(1) @go go: 1, @write_together(1) in: WIDTH ) -> ( out: WIDTH, @done done: 1 ); } // Computes the unsigned value b^e, where // b is the `base` and e is the `exp`. component pow(base: 32, exp: 32) -> (out: 32) { cells { t = std_reg(32); count = std_reg(32); mul = std_mult_pipe(32); lt = std_lt(32); incr = std_add(32); } wires { group init<"static"=1> { t.in = 32'd1; t.write_en = 1'd1; count.in = 32'd0; count.write_en = 1'd1; init[done] = t.done & count.done ? 1'd1; } group do_mul { mul.left = base; mul.right = t.out; mul.go = !mul.done ? 1'd1; t.in = mul.out; t.write_en = mul.done; do_mul[done] = t.done; } group incr_count<"static"=1> { incr.left = 32'd1; incr.right = count.out; count.in = incr.out; count.write_en = 1'd1; incr_count[done] = count.done; } group cond<"static"=0> { lt.right = exp; lt.left = count.out; cond[done] = 1'd1; } out = t.out; } control { seq { init; while lt.out with cond { par { do_mul; incr_count; } } } } }