blob: 858db99a5a8fb81ab154dbafede4587a07932320 [file] [log] [blame]
`default_nettype none
// Keep I/O fixed for TinyTapeout
module user_module_019235602376235615(
input [7:0] io_in,
output [7:0] io_out
);
// 6bit angles and 6 bit outputs
// y0 = 0, x0 = 0.60728
/*
How to convert angles to binary angles:
angle = 180/62*bin_angle
Convert sine and cosine values to binary:
value = 2/62*bin_value
*/
wire clk = io_in[0];
wire reset = io_in[1];
wire [5:0] z0 = io_in[7:2]; // input angle supports from -90 to +90 degrees
// ROM
reg [5:0]x0;
reg [5:0]angle[5:0];
always @(posedge clk) begin
x0 <= 6'd19; // x0 = 0.60728
angle[0] <= 6'd16; // angle 0 = 45
angle[1] <= 6'd9; // angle 1 = 26.565
angle[2] <= 6'd5; // angle 2 = 14.036
angle[3] <= 6'd2; // angle 3 = 7.125
angle[4] <= 6'd1; // angle 4 = 3.576
angle[5] <= 6'd1; // angle 5 = 1.7899
end
// Registers
reg [5:0] reg_x, reg_y, reg_x_next, reg_y_next, reg_z, reg_z_next;
reg en;
always @(posedge clk) begin
if (reset) begin
reg_x <= x0;
reg_y <= 0;
reg_z <= z0;
end else if (en) begin
reg_x <= reg_x_next;
reg_y <= reg_y_next;
reg_z <= reg_z_next;
end
end
// ALU
wire d;
assign d = reg_z[5];
always @(*) begin
if (d) begin // if d then x is add and y is sub and z is add
reg_x_next <= reg_x + ($signed(reg_y) >>> i);
reg_y_next <= reg_y - ($signed(reg_x) >>> i);
reg_z_next <= reg_z + angle[i];
end else begin // if !d then x is sub and y is add and z is sub
reg_x_next <= reg_x - ($signed(reg_y) >>> i);
reg_y_next <= reg_y + ($signed(reg_x) >>> i);
reg_z_next <= reg_z - angle[i];
end
end
// Control unit
reg [1:0] state;
`define RESET 2'b0
`define CALC 2'd1
`define DONE 2'd2
reg [2:0]i;
reg done;
always @(posedge clk) begin
case (state)
`RESET: begin
done <= 0;
i <= 0;
if (!reset) begin
state <= `CALC;
en <= 1;
end
end
`CALC: begin
if ( i < 5) begin
i <= i+1;
if (i == 4)
en <= 0;
end
else begin
state <= `DONE;
end
end
`DONE: begin
done <= 1;
if (reset)
state <= `RESET;
end
default: begin
state <= 0;
end
endcase
end
// Ooutput controler
assign io_out[7] = done;
wire x_yb;
assign x_yb = clk;
assign io_out[6] = x_yb;
wire [5:0] data_out;
assign io_out[5:0] = data_out;
assign data_out = (done) ? (clk) ? reg_x : reg_y : 0;
endmodule