// lab 3
module Freq_Selector(input clk ,rst , ld , input [3:0] par_load ,output co);
reg [8:0] counter ;
reg [3:0] hard_coded = 4'b1010;
reg load ;
always @(posedge clk , posedge rst , posedge load)
begin
if(rst)
counter <= 9'b0;
else if(load)
counter <= {par_load, hard_coded};
else
counter <= counter + 1;
end
assign co = &counter;
assign load = ld | (&counter);
endmodule
module counter_8bit(input clk , rst , output [7:0] Counter);
reg [7:0] counter;
always @(posedge clk , posedge rst)
begin
if(rst)
counter <= 8'b0;
else
counter <= counter + 1;
end
assign Counter = counter;
endmodule
module wave_Form_generator(input clk , rst ,output [7:0] square , Reciprocal, Triangular);
reg [7:0] counter;
wire [7:0] CCounter;
counter_8bit cnt(clk , rst , CCounter);
assign counter = CCounter;
// square wave
assign square = (counter[7]) ? (8'b11111111) : (8'b00000000);
// reciprocal wave
assign Reciprocal = (8'b11111111/((8'b11111111 - counter)+1));
// triangular wave
assign Triangular = (~counter[7]) ? (2*counter) : (9'b11111111 - 2*counter);
endmodule
module AMP_Selector(input clk , rst , input [1:0] select , input [7:0] input_in , output [7:0] output_out );
assign output_out = (select == 2'b00) ? ( input_in ) : (select == 2'b01) ? (input_in/2) : (select == 2'b10) ? (input_in/4) : (input_in/8);
endmodule
module counter_6bit(input clk , rst , output out , output [5:0] Counter);
reg [5:0] counter;
always @(posedge clk , posedge rst)
begin
if(rst)
counter <= 8'b0;
else
counter <= counter + 1;
end
assign out = &counter;
assign Counter = counter;
endmodule
module DDS_Unit(input clk, rst, output reg [8:0] sin_out , reg [8:0] half_sin_out , reg [8:0] full_sin_out);
reg [1:0] controler_nx_state, controler_px_state;
reg sign_bit, phase_bit;
parameter [1:0] S0 = 2'b00, S1 = 2'b01, S2 = 2'b10, S3 = 2'b11;
reg [8:0] sin_wave;
wire co;
wire [5:0] address;
wire [5:0] address_two;
assign address_two = (~address) + 1;
counter_6bit cnt(clk, rst, co, address);
// mux 2:1
wire [5:0] mux_out;
assign mux_out = (~phase_bit) ? address : address_two;
// read from rom file mif file
reg [7:0] rom_out;
reg [7:0] rom [0:63];
always @* begin
full_sin_out = (sign_bit) ? ({0 ,~sin_out[7:0] + 1'b1}) : sin_out;
end
always @* begin
half_sin_out = (~sign_bit) ? sin_out : 9'b010000000;
end
initial $readmemb("sine.mem", rom);
assign rom_out = rom[mux_out];
reg [7:0] mux_8_out;
assign mux_8_out = ((~(|address)) & phase_bit) ? 8'b11111111 : rom_out;
always @(*) begin
sin_out = (sign_bit) ? {1'b0, (~mux_8_out+1'b1)} : ({1'b0, mux_8_out});
end
always @(posedge clk or posedge rst) begin
if (rst)
controler_px_state <= S0;
else
controler_px_state <= controler_nx_state;
end
always @(*) begin
case (controler_px_state)
S0: begin
controler_nx_state = (co) ? S1 : S0;
end
S1: begin
controler_nx_state = (co) ? S2 : S1;
end
S2: begin
controler_nx_state = (co) ? S3 : S2;
end
S3: begin
controler_nx_state = (co) ? S0 : S3;
end
endcase
end
always @(*) begin
case (controler_px_state)
S0: begin
sign_bit = 1'b0;
phase_bit = 1'b0;
end
S1: begin
sign_bit = 1'b0;
phase_bit = 1'b1;
end
S2: begin
sign_bit = 1'b1;
phase_bit = 1'b0;
end
S3: begin
sign_bit = 1'b1;
phase_bit = 1'b1;
end
endcase
end
endmodule
module mux_6_1(input [7:0] in0 , in1 , in2 , in3 , in4 , in5 , input [2:0] select , output [7:0] out);
assign out = (select == 3'b000) ? (in0) : (select == 3'b001) ? (in1) : (select == 3'b010) ? (in2) : (select == 3'b011) ? (in3) : (select == 3'b100) ? (in4) : (in5);
endmodule
module PWM(input clk , rst , input [7:0] duty_cycle , output reg pwm_out);
reg [7:0] counter;
always @(posedge clk or posedge rst) begin
if (rst)
counter <= 8'b0;
else
counter <= counter + 1;
end
always @(*) begin
pwm_out = (counter < duty_cycle) ? 8'b1 : 8'b0;
end
endmodule
module Top_module(input clk , rst , key , input[2:0] select_3 , input [1:0] select_2 , input[4:0] select_5 , output out );
wire clk_star ;
Freq_Selector fs(clk , rst , key , select_5 , clk_star);
wire [7:0] square,Reciprocal,Triangular;
wave_Form_generator wfg(clk_star , rst , square,Reciprocal,Triangular);
wire [7:0] sin_out , half_sin_out , full_sin_out;
DDS_Unit DSS(clk_star , rst , sin_out , half_sin_out , full_sin_out);
wire [7:0] select_6_1_out;
mux_6_1 mux_6_1_inst(Reciprocal , square , Triangular , sin_out,full_sin_out , half_sin_out , select_3 , select_6_1_out);
wire [7:0] amp_out;
AMP_Selector amp(clk_star , rst , select_2 , select_6_1_out , amp_out);
wire PWM_out;
PWM pwm(clk , rst , amp_out , PWM_out);
assign out = PWM_out;
endmodule
module top_tb();
reg clk=0,rst=0,key=0;
reg [2:0] select_3 = 3'b001;
reg [1:0] select_2 = 2'b00;
reg [4:0] select_5 = 5'b00000;
Top_module top(clk,rst,key,select_3,select_2,select_5,out);
always #50 clk = ~clk;
initial begin
#100 rst = 1'b1;
#100 rst = 1'b0;
// #100 select_3 = 3'b000;
// #100 select_2 = 2'b00;
// #100 select_5 = 5'b00000;
#100 key = 1'b1;
#100 key = 1'b0;
#1000000;
$stop;
end
endmodule