Q1: write Verilog code to generate below waveform:
Q2: write Verilog code to generate below waveform:
Since there is one delay after the rising edge of data in, three delays after the negedge of din, I write a moore FSM.
module delay_reg(rst,clk,d_in,d_out); input rst,clk, d_in; output reg d_out; reg [1:0] c_s, n_s; parameter s0=2'b00, s1=2'b01,s2=2'b10,s3=2'b11; always @(posedge clk)begin if(rst) c_s<=s0; else c_s<= n_s;end always@(*)begin case(c_s) s0: begin if(d_in) n_s=s1; else n_s=s0; end s1: begin if(!d_in) n_s=s2; else n_s=s1; end s2: n_s=s3; s3: n_s=s0; default: n_s=s0; endcase end always@(posedge clk) begin case(c_s) s0:d_out=0; s1:d_out=1; s2:d_out=1; s3:d_out=1; endcase end endmoduleQ3 Design an FSM to detect a sequence 10110:
I designed a Mealy machine:
module pattern_m(clk, rst, d_in, d_out); input clk, rst, d_in; output d_out; reg [2:0] cstate, nstate; parameter s0=3'b000, s1=3'b001,s2=3'b010,s3=3'b011,s4=3'b100; always@(posedge clk or negedge rst)begin if(~rst) cstate <=0; else cstate <= nstate; end always@(*)begin case(cstate) s0: if(d_in) nstate=s1; else nstate =s0; s1: if(~d_in) nstate = s2; else nstate = s1; s2: if(d_in) nstate = s3; else nstate = s0; s3: if(d_in) nstate = s4; else nstate = s1; s4: if(~d_in) nstate = s0; else nstate = s1; default: nstate =s0; endcase end assign d_out = (~d_in)&&(cstate==s4); endmoduleQ4
Design an FSM (Finite State Machine) to detect more than one "1"s in the last 3 samples.
Use the Mealy machine:
module three_sig_detect(din,clk, rst, dout, cstate); input din, clk, rst; output reg dout; output reg [1:0] cstate; reg [1:0] nstate; parameter s0=2'b00, s1=2'b01, s2=2'b10, s3=2'b11; always@(posedge clk or negedge rst)begin if(~rst) cstate <= s0; else cstate <= nstate; end always@(*)begin case(cstate) s0:if(din) nstate=s1; else nstate=s0; s1:if(din) nstate=s3; else nstate=s2; s2:if(din) nstate=s1; else nstate=s0; s3:if(din) nstate=s3; else nstate=s1; default: nstate=s0; endcase end always@(posedge clk or negedge rst)begin if(~rst) dout <= 0; else case(cstate) s0: dout <= 0; s1: if(din) dout <= 1; else dout <= 0; s2: if(din) dout <= 1; else dout <= 0; s3: dout <= 1; default: dout <= 0; endcase end //assign dout=((cstate==s3)?1:0)||((cstate==3)&&din)||((cstate==1)&&din); endmoduleQ5 Divide the clock by 3/2, for example, input frequency=50 Hz, output frequency = 33.33Hz
Reference: https://www.edaboard.com/showthread.php?42620-how-to-get-an-2-3-clock-divider-using-VHDL
module div_2by3(clkout, clkin, reset_n); input clkin, reset_n; output clkout; reg [1:0] clk_by3_pos, clk_by3_neg; //two regs that counts from 0 to 2 always @(posedge clkin or negedge reset_n) //posedge edge of clk_out if (!reset_n) clk_by3_pos <= 0; else if (clk_by3_pos == 2) clk_by3_pos <= 0; else clk_by3_pos <= clk_by3_pos + 1; always @(negedge clkin or negedge reset_n) //negedge edge of clk_out if (!reset_n) clk_by3_neg <= 0; else if (clk_by3_neg == 2) clk_by3_neg <= 0; else clk_by3_neg <= clk_by3_neg + 1; assign clkout = (~clk_by3_neg[0] & clk_by3_pos[0]) | (clk_by3_neg[1] & clk_by3_pos[1]); endmoduleQ6 Peak detector
module peak_detect(clk, track, din, dout); input clk, track; input [2:0] din; output [2:0] dout; reg [2:0] d_reg; always@(posedge clk or posedge track)begin if (track) d_reg <= d_reg; else if(din > d_reg) d_reg <= din; else d_reg <= d_reg; end assign dout = d_reg; endmoduleClock Divider (ratio = 40)
module clk_divider #(parameter N = 40,WIDTH = 7) (input bus_clk, output reg clk_out, output reg [WIDTH:0]counter); always @(posedge bus_clk) begin if (counter == N-1) begin counter <= 0; end else begin counter <= counter + 1; end end always @(posedge bus_clk) begin if (counter == N-1) begin clk_out <= !clk_out; end end endmodule