| `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 |