2024-10-06 04:18:41 +00:00
|
|
|
module renderer
|
|
|
|
#(
|
2024-10-17 15:11:06 +00:00
|
|
|
parameter ITERATIONS = 220,
|
|
|
|
parameter OUTPUT_WIDTH = 8,
|
2024-10-06 04:18:41 +00:00
|
|
|
localparam ITERATION_WIDTH = $clog2(ITERATIONS + 1),
|
2024-10-09 19:18:36 +00:00
|
|
|
localparam SHIFT_AMOUNT = ITERATION_WIDTH - OUTPUT_WIDTH,
|
|
|
|
localparam FRACTION_BITS = 13
|
2024-10-06 04:18:41 +00:00
|
|
|
)(
|
|
|
|
input wire clk,
|
|
|
|
input wire rst,
|
|
|
|
input wire start,
|
2024-10-09 19:18:36 +00:00
|
|
|
input wire [7:0] x,
|
|
|
|
input wire [7:0] y,
|
|
|
|
input wire signed [14:0] cx,
|
|
|
|
input wire signed [14:0] cy,
|
|
|
|
input wire [2:0] zoom,
|
2024-10-06 04:18:41 +00:00
|
|
|
output reg done,
|
|
|
|
output reg [OUTPUT_WIDTH-1:0] iters
|
|
|
|
);
|
|
|
|
|
2024-10-09 19:18:36 +00:00
|
|
|
reg signed [15:0] x_reg;
|
|
|
|
reg signed [15:0] y_reg;
|
|
|
|
reg signed [15:0] z_real;
|
|
|
|
reg signed [15:0] z_imag;
|
2024-10-06 04:18:41 +00:00
|
|
|
reg [ITERATION_WIDTH-1:0] current_iteration;
|
|
|
|
|
2024-10-09 19:18:36 +00:00
|
|
|
wire signed [31:0] a_squared_p;
|
|
|
|
wire signed [31:0] b_squared_p;
|
|
|
|
wire signed [31:0] ab_p;
|
2024-10-06 04:18:41 +00:00
|
|
|
|
2024-10-09 19:18:36 +00:00
|
|
|
wire signed [31:0] apb_squared;
|
|
|
|
wire signed [31:0] asb_squared;
|
|
|
|
|
|
|
|
wire signed [31:0] ab;
|
2024-10-06 04:18:41 +00:00
|
|
|
|
|
|
|
always_ff @(posedge clk) begin
|
|
|
|
done <= 1'b0;
|
|
|
|
|
2024-10-09 19:18:36 +00:00
|
|
|
if (current_iteration == ITERATIONS) begin
|
|
|
|
x_reg <= '0;
|
|
|
|
y_reg <= '0;
|
|
|
|
|
|
|
|
z_real <= '0;
|
|
|
|
z_imag <= '0;
|
|
|
|
|
|
|
|
current_iteration <= '0;
|
|
|
|
iters <= '0;
|
|
|
|
|
|
|
|
done <= 1'b1;
|
|
|
|
end else if (apb_squared >= 32'h4 << (2 * FRACTION_BITS)) begin
|
2024-10-06 04:18:41 +00:00
|
|
|
x_reg <= '0;
|
|
|
|
y_reg <= '0;
|
|
|
|
|
|
|
|
z_real <= '0;
|
|
|
|
z_imag <= '0;
|
|
|
|
|
|
|
|
current_iteration <= '0;
|
2024-10-09 19:18:36 +00:00
|
|
|
iters <= OUTPUT_WIDTH'(current_iteration >> SHIFT_AMOUNT);
|
2024-10-06 04:18:41 +00:00
|
|
|
|
|
|
|
done <= 1'b1;
|
|
|
|
end else if (current_iteration == 0) begin
|
|
|
|
// store c for later
|
2024-10-09 19:18:36 +00:00
|
|
|
x_reg <= cx + (16'(x) << zoom) + 16'hC000;
|
|
|
|
y_reg <= cy + (16'(y) << zoom) + 16'hC000;
|
2024-10-06 04:18:41 +00:00
|
|
|
|
|
|
|
// add c for first iteration.
|
|
|
|
// no need to include z as it is initially (0, 0)
|
2024-10-09 19:18:36 +00:00
|
|
|
z_real <= cx + (16'(x) << zoom) + 16'hC000;
|
|
|
|
z_imag <= cy + (16'(y) << zoom) + 16'hC000;
|
2024-10-06 04:18:41 +00:00
|
|
|
|
|
|
|
if (!start) begin
|
|
|
|
current_iteration <= '0;
|
2024-10-09 19:18:36 +00:00
|
|
|
end else begin
|
|
|
|
current_iteration <= current_iteration + 1'b1;
|
2024-10-06 04:18:41 +00:00
|
|
|
end
|
|
|
|
end else begin
|
2024-10-09 19:18:36 +00:00
|
|
|
z_real <= asb_squared[15+FRACTION_BITS:FRACTION_BITS] + x_reg;
|
|
|
|
z_imag <= ab[15+FRACTION_BITS:FRACTION_BITS] + y_reg;
|
|
|
|
current_iteration <= current_iteration + 1'b1;
|
2024-10-06 04:18:41 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
if (rst) begin
|
2024-10-09 19:18:36 +00:00
|
|
|
x_reg <= '0;
|
|
|
|
y_reg <= '0;
|
|
|
|
z_real <= '0;
|
|
|
|
z_imag <= '0;
|
2024-10-06 04:18:41 +00:00
|
|
|
current_iteration <= '0;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
multiplier m1(.clk(clk), .a(z_real), .b(z_real), .product(a_squared_p));
|
|
|
|
multiplier m2(.clk(clk), .a(z_imag), .b(z_imag), .product(b_squared_p));
|
|
|
|
multiplier m3(.clk(clk), .a(z_real), .b(z_imag), .product(ab_p));
|
|
|
|
|
2024-10-09 19:18:36 +00:00
|
|
|
assign apb_squared = a_squared_p + b_squared_p;
|
|
|
|
assign asb_squared = a_squared_p - b_squared_p;
|
|
|
|
assign ab = ab_p << 1'b1;
|
2024-10-06 04:18:41 +00:00
|
|
|
|
|
|
|
endmodule
|