blob: 91c458927039ce311711a3f84122c4604da25835 [file] [log] [blame]
// TinyTapeout Square Root Engine
// Copyright (C) 2022 Davit Margarian
`default_nettype none
// Top level io for this module should stay the same to fit into the scan_wrapper.
// The pin connections within the user_module are up to you,
// although (if one is present) it is recommended to place a clock on io_in[0].
// This allows use of the internal clock divider if you wish.
module udxs_sqrt_top(
input [7:0] io_in,
output [7:0] io_out
);
wire [10:0] result;
assign io_out = result[7:0];
udxs_sqrt sqrt_core(
.clk(io_in[0]),
.query({io_in[7:1], 4'b0}),
.result(result)
);
endmodule
// SQRT Iteration Unit
// Copyright (C) 2022 Davit Margarian
module udxs_sqrtiu (
input [10:0] prev_att,
input [10:0] prev_eps,
input [10:0] prev_res,
output [10:0] this_att,
output [10:0] this_eps,
output [10:0] this_res
);
assign this_att = {1'b0, prev_att[10:1]};
wire [10:0] this_delta_term1_half;
wire [10:0] this_delta;
reg [3:0] this_att_msb;
wire [4:0] this_att_sq_exp;
wire [10:0] this_att_sq;
assign this_att_sq_exp = {this_att_msb, 1'b0};
assign this_att_sq = 11'b1 << this_att_sq_exp;
assign this_delta_term1_half = prev_res << this_att_msb;
assign this_delta = {this_delta_term1_half[9:0], 1'b0} + this_att_sq;
wire cond_met;
assign cond_met = this_delta <= prev_eps;
assign this_eps = cond_met ? prev_eps - this_delta : prev_eps;
assign this_res = cond_met ? prev_res | this_att : prev_res;
integer msb_idx;
always @* begin
this_att_msb = 0;
for (msb_idx=0; msb_idx < 11; msb_idx++) begin
if(this_att == (1 << msb_idx))
this_att_msb = msb_idx[3:0];
end
end
endmodule
// SQRT Control Logic
// Copyright (C) 2022 Davit Margarian
module udxs_sqrt(
input clk,
input [10:0] query,
output reg [10:0] result
);
reg [10:0] att;
reg [10:0] eps;
reg [10:0] res;
wire [10:0] att_mid;
wire [10:0] res_mid;
wire [10:0] eps_mid;
wire [10:0] att_next;
wire [10:0] res_next;
wire [10:0] eps_next;
udxs_sqrtiu iteratorA(
.prev_att(att),
.prev_eps(eps),
.prev_res(res),
.this_att(att_mid),
.this_eps(eps_mid),
.this_res(res_mid)
);
udxs_sqrtiu iteratorB(
.prev_att(att_mid),
.prev_eps(eps_mid),
.prev_res(res_mid),
.this_att(att_next),
.this_eps(eps_next),
.this_res(res_next)
);
reg [1:0] iteration;
always @(posedge clk) begin
if (iteration != 3) begin
att <= att_next;
eps <= eps_next;
res <= res_next;
iteration <= iteration + 1;
end else begin
result <= res;
eps <= query;
att <= 1 << 6;
res <= 0;
iteration <= 0;
end
end
endmodule