module squarewave(input logic clk, input logic rst, output logic [15:0] addr, input logic [7:0] data, input logic button, output logic [1:0] square_out); logic loadctr, timeiszero; typedef enum logic[2:0] {GETTIMELOW = 3'b000, GETTIMEHIGH = 3'b001, GETFREQLOW = 3'b010, GETFREQHIGH = 3'b011, GETFREQ2LOW = 3'b100, GETFREQ2HIGH = 3'b101, SENDDATA = 3'b110, IDLE = 3'b111} state_t; state_t state; // Address output depends on 3 LSB bits of the state. always @* begin addr[2:0] = state[2:0]; end // Synchronize button input logic button_sync1, button_sync2; always_ff @(posedge clk) begin button_sync1 <= button; button_sync2 <= button_sync1; end logic inc_memaddr; always_ff @(posedge clk) begin if(rst) begin addr[15:3] <= 0; end else begin if(inc_memaddr) begin addr[15:3] <= addr[15:3] + 1; end end end always_ff @(posedge clk) begin if(rst) begin state <= IDLE; end else begin case(state) GETFREQ2HIGH: begin state <= SENDDATA; end SENDDATA: begin if(timeiszero) begin state <= GETTIMELOW; end else begin state <= SENDDATA; end end IDLE: begin if(button_sync2) begin state <= GETTIMELOW; end end default: begin state <= state.next(); end endcase // case (state) end end // always_ff @ (posedge clk) logic loadlow1, loadhigh1; logic loadlow2, loadhigh2; always_comb begin loadlow1 = 0; loadhigh1 = 0; loadlow2 = 0; loadhigh2 = 0; inc_memaddr = 0; case(state) GETFREQLOW: begin loadlow1 = 1; end GETFREQHIGH: begin loadhigh1 = 1; end GETFREQ2LOW: begin loadlow2 = 1; end GETFREQ2HIGH: begin loadhigh2 = 1; inc_memaddr = 1; end endcase end squarewavegen synth1(.loadlow(loadlow1), .loadhigh(loadhigh1), .square_out(square_out[1]), .*); squarewavegen synth2(.loadlow(loadlow2), .loadhigh(loadhigh2), .square_out(square_out[0]), .*); logic [11+8:0] timecount; always_ff @(posedge clk) begin if(state == GETTIMEHIGH) begin timecount[19:16] <= data; end else if(state == GETTIMELOW) begin timecount[15:8] <= data; timecount[7:0] <= 255; end else begin timecount <= timecount - 1; end if(timecount) begin timeiszero <= 0; end else begin timeiszero <= 1; end end endmodule // synth module squarewavegen(input logic clk, rst, input logic loadlow, input logic loadhigh, input logic [7:0] data, output logic square_out); logic [15:0] counter, counterval; logic counteriszero; always_ff @(posedge clk) begin counteriszero <= counter ? 1'b0 : 1'b1; if(loadlow) begin counterval[7:0] <= data; end else if(loadhigh) begin counterval[15:8] <= data; end else begin if(counteriszero) begin if(counterval[15:8] != 0) begin square_out <= !square_out; end counter <= counterval; end else begin counter <= counter - 1; end end if(rst) begin square_out <= 0; counter <= 0; counterval <= 0; counteriszero <= 0; end end endmodule