module circle_gen(CLK, reset, lock, init, busy, done, Ax, Ay, Az, Bx, By, Bz, stepsize); input CLK, reset, lock, init; wire CLK, reset, lock, init; output busy, done; reg busy, done; output [15:0] Ax, Ay, Az, Bx, By, Bz; wire [15:0] Ax, Ay, Az, Bx, By, Bz; reg [15:0] prev_x, prev_y, prev_z; reg [15:0] next_x, next_y, next_z; reg [15:0] first_x, first_y, first_z; assign Ax[15:0] = prev_x; assign Ay[15:0] = prev_y; assign Az[15:0] = prev_z; assign Bx[15:0] = next_x; assign By[15:0] = next_y; assign Bz[15:0] = next_z; input [15:0] stepsize; wire [15:0] stepsize; reg [3:0] state; reg [15:0] d_step; reg [15:0] cur_step; parameter done_looping = 4'd0, looping = 4'd1, wait_for_init_low = 4'd2, debug_circle = 1'b0; wire [8:0] sine_addr; assign sine_addr[8:0] = cur_step[8:0]; wire [15:0] sine_out; wire [8:0] cos_addr; assign cos_addr[8:0] = cur_step[8:0] + 9'd128; wire [15:0] cos_out; sineTable9x16bit sineTable(CLK, sine_addr, sine_out); sineTable9x16bit cosTable(CLK, cos_addr, cos_out); always @(posedge CLK) begin if (reset) begin cur_step <= 16'd0; prev_x <= 16'd0; prev_y <= 16'd0; prev_z <= 16'd0; next_x <= 16'd0; next_y <= 16'd0; next_z <= 16'd0; busy <= 1'b0; done <= 1'b0; state <= done_looping; if (debug_circle) $display("circle_gen: being reset"); end else if (lock) begin case (state) done_looping: begin if (init == 1'b1) begin // start querying the sine table now cur_step <= stepsize; // delta step. 1, 2, 3, ... d_step <= stepsize; // not busy yet (no valid results out) busy <= 1'b0; // not done yet done <= 1'b0; state <= looping; end // if (init == 1'b1) else begin busy <= 1'b0; done <= 1'b0; end end looping: begin if (cur_step > 512) begin // not done yet. busy <= 1'b1; done <= 1'b0; // advance prev_[xyz] prev_x[15:0] <= next_x[15:0]; prev_y[15:0] <= next_y[15:0]; prev_z[15:0] <= next_z[15:0]; // set next_[xyz] to 0 next_x[15:0] <= first_x[15:0]; next_y <= 16'd0; next_z <= 16'd0; state <= wait_for_init_low; end else begin // initial case prev_x[15:0] <= next_x[15:0]; prev_y[15:0] <= next_y[15:0]; prev_z[15:0] <= next_z[15:0]; next_x[15:0] <= cos_out[15:0]; next_y[15:0] <= sine_out[15:0]; next_z[15:0] <= 16'd0; // turn busy on after the first line. don't draw center if (cur_step != stepsize) begin busy <= 1'b1; end else if (cur_step == stepsize) begin // save the first point so we can complete circle in the end first_x[15:0] <= cos_out[15:0]; first_y[15:0] <= sine_out[15:0]; first_z[15:0] <= 16'd0; end // not done done <= 1'b0; // advance cur_step <= cur_step + d_step; end // else: !if(cur_step > 512) end // case: looping wait_for_init_low: begin // now we're done busy <= 1'b0; done <= 1'b1; if (~init) begin state <= done_looping; end end endcase // case (state) end end // always @ (posedge CLK) endmodule // circle_gen