pico-ice-video/ice/mandelbrot/source/impl_1/top.sv

131 lines
2.8 KiB
Systemverilog
Raw Normal View History

2024-09-26 14:28:41 +00:00
module top
(
input wire clk,
input wire dir,
inout wire req,
output wire fin,
inout wire [7:0] data
2024-09-26 14:28:41 +00:00
);
localparam RENDER_COUNT = 4;
reg req_last;
reg [7:0] waddr;
reg [7:0] raddr;
wire [7:0] command;
2024-10-06 04:18:41 +00:00
ram command_buffer(.wclk(clk), .rclk(clk), .waddr(waddr), .raddr(raddr), .data_in(data), .write_en(dir && req), .data_out(command));
wire [7:0] iters[RENDER_COUNT];
wire [7:0] x[RENDER_COUNT];
wire [7:0] y[RENDER_COUNT];
2024-10-06 04:18:41 +00:00
wire [RENDER_COUNT-1:0] renderer_done;
reg [RENDER_COUNT-1:0] renderer_done_r;
2024-10-06 04:18:41 +00:00
2024-10-09 19:18:36 +00:00
wire coords_fin;
reg coords_inc;
2024-10-06 04:18:41 +00:00
2024-10-09 19:18:36 +00:00
reg coords_inc_last;
reg [5:0] coords_fin_last;
genvar ri;
generate
for (ri = 0; ri < RENDER_COUNT; ri = ri + 1) begin
renderer r(.clk(clk), .rst(dir), .start(!dir && !coords_fin && !renderer_done[ri] && !renderer_done_r[ri]), .x(x[ri]), .y(y[ri]), .cx(15'h1000), .cy(15'h2000), .zoom(3'd6), .done(renderer_done[ri]), .iters(iters[ri]));
end
endgenerate
2024-10-06 04:18:41 +00:00
coords #(.POS_COUNT(RENDER_COUNT)) coords_inst(.clk(clk), .rst(dir), .inc(coords_inc), .x(x), .y(y), .finished(coords_fin));
2024-10-09 19:18:36 +00:00
wire fb_clk;
reg [16:0] fb_addr;
2024-10-09 19:18:36 +00:00
wire fb_we;
wire [15:0] fb_data_out;
reg [15:0] fb_data_out_last;
2024-10-09 19:18:36 +00:00
reg fb_half_out;
spram_big fb
(
.clk(fb_clk),
.we
({
{ fb_we, fb_we, fb_we, fb_we },
{ fb_we, fb_we, fb_we, fb_we },
{ fb_we, fb_we, fb_we, fb_we },
{ fb_we, fb_we, fb_we, fb_we }
}),
.addr(fb_addr[15:0]),
.data_in
({
{ 8'd128, iters[0] + 8'd16 },
{ 8'd128, iters[1] + 8'd16 },
{ 8'd128, iters[2] + 8'd16 },
{ 8'd128, iters[3] + 8'd16 }
}),
.data_out(fb_data_out)
);
2024-09-26 14:28:41 +00:00
always_ff @(posedge clk) begin
req_last <= req;
coords_fin_last[5:1] <= coords_fin_last[4:0];
coords_fin_last[0] <= coords_fin && !dir;
2024-10-09 19:18:36 +00:00
coords_inc_last <= coords_inc && !dir;
2024-09-26 14:28:41 +00:00
if (dir) begin
renderer_done_r <= '0;
end else begin
integer i;
for (i = 0; i < RENDER_COUNT; i = i + 1) begin
if (renderer_done[i]) begin
renderer_done_r[i] <= 1;
end
end
if (renderer_done_r == '1) begin
renderer_done_r <= '0;
coords_inc <= 1;
end else begin
coords_inc <= 0;
end
end
if (dir) begin
raddr <= 0;
2024-10-09 19:18:36 +00:00
fb_addr <= 0;
fb_half_out <= 0;
if (req && req_last) begin
waddr <= waddr + 1;
end else begin
waddr <= 0;
end
2024-10-09 19:18:36 +00:00
end else if (coords_fin) begin
if (!coords_fin_last[0] || !coords_fin_last[1]) begin
2024-10-09 19:18:36 +00:00
fb_addr <= 0;
fb_half_out <= 0;
end else begin
fb_half_out <= !fb_half_out;
if (fb_half_out) begin
fb_data_out_last <= fb_data_out;
2024-10-09 19:18:36 +00:00
fb_addr <= fb_addr + 1;
end
end
end else if (coords_inc_last) begin
fb_addr <= fb_addr + RENDER_COUNT;
2024-09-26 14:28:41 +00:00
end
end
2024-10-09 19:18:36 +00:00
assign fb_clk = clk;
assign fb_we = coords_inc && !coords_fin;
assign fin = !dir && coords_fin_last[5] && fb_addr >= 65536;
2024-10-06 04:18:41 +00:00
assign req = dir ? 'Z : coords_fin_last[5];
assign data = dir ? 'Z : (fb_half_out ? fb_data_out_last[15:8] : fb_data_out_last[7:0]);
2024-09-26 14:28:41 +00:00
endmodule