CID Aplicatii 13

De la WikiLabs
Jump to navigationJump to search

Automate finite. Exercitii

Exercitiul 1

Sa se implementeze un circuit care genereaza un semnal PWM cu un factor de umplere ce variaza triungular, la fiecare front cazator al unui semnal de intrare.

Schema circuitului este:

FSM Exercitiu.png

Modulele componente ale circuitului sunt:

  • FallingEdgeDetector: Automat ce detecteaza fronturile descrescatoare ale semnalului de intrare.
  • TriangularCounter: Automat ce genereaza la iesire secventa de numere 64, 128, 192, 255, 192, 128, 64.
  • Counter: Numarator pe 8 biti cu reset sincron.
  • COMP: Comparator cu doua intrari pe 8 biti. Iesirea sa va fi 1 atunci cand counter < out si 0 in rest.

Modulul Counter

module Counter(
    input clock,
    input reset,
    output reg [7:0] count
);

always@(posedge clock) begin
    if(reset == 0)
        count <= 0;
    else
        count <= count + 1;
end

endmodule

Modulul COMP

module Comparator(
    input [7:0] in0,
    input [7:0] in1,
    output comp_out
);

assign comp_out = (in0 < in1) ? 1 : 0;

endmodule

Modulul FallingEdgeDetector

Automatul ce detecteaza fronturile descrescatoare are un singur semnal de intrare in, care reprezinta semnalul analizat si o singura iesire, out, generand pe aceasta un puls lung cat o perioada de ceas la fiecare aparitie a unui front descrescator pe in.

Graful automatului este:

Graf FSM falling edge.png

module FallingEdgeDetector(
    input clock,
    input in,
    input reset,
    output out
);

localparam Q0 = 2'b00;
localparam Q1 = 2'b01;
localparam Q2 = 2'b10;

reg [1:0] state, state_next;

always@(posedge clock) begin
    if(reset == 0)
        state <= Q0;
    else
        state <= state_next;
end

always@(*) begin
    state_next = state;
    case(state)
        Q0: begin
                if(in == 0) state_next = Q1;
            end
        Q1: begin
                if(in == 1) state_next = Q0;
                if(in == 0) state_next = Q2;
            end
        Q2: begin
                if(in == 1) state_next = Q0;
            end
        default: state_next = Q0;
    endcase
end

assign out   = (state == Q1);

endmodule

Modulul TriangularCounter

Acest modul este un automat ce genereaza la iesire secventa de numere 64, 128, 192, 255, 192, 128, 64.

Graful automatului este:

Graf FSM triangular cnt.png

module TriangularCounter(
    input clock,
    input in,
    input reset,
    output reg [7:0] out
);

localparam Q0 = 3'b000;
localparam Q1 = 3'b001;
localparam Q2 = 3'b010;
localparam Q3 = 3'b011;
localparam Q4 = 3'b100;
localparam Q5 = 3'b101;

reg [2:0] state, state_next;

always@(posedge clock) begin
    if(reset == 0)
        state <= Q0;
    else
        state <= state_next;
end

always@(*) begin
    state_next = state;
    case(state)
        Q0: if(in == 1) state_next = Q1;
        Q1: if(in == 1) state_next = Q2;
        Q2: if(in == 1) state_next = Q3;
        Q3: if(in == 1) state_next = Q4;
        Q4: if(in == 1) state_next = Q5;
        Q5: if(in == 1) state_next = Q0;
        default: state_next = Q0;
    endcase
end

always@(*) begin
    if(state == Q0)
        out = 64;
    if((state == Q1) || (state == Q5))	
        out = 128;
    if((state == Q2) || (state == Q4))	
        out = 192;	
    if(state == Q3)
        out = 255;
end

endmodule

Modulul TOP

Implementarea modulului TOP

module TOP(
    input clock,
    input reset,
    input in, 
    output comp_out
);

wire w1;
wire [7:0] count, tricount;

FallingEdgeDetector FEDET(
    .clock(clock),
    .in(in),
    .reset(reset),
    .out(w1)
);

Counter COUNT(
    .clock(clock),
    .reset(reset),
    .count(count)
);

TriangularCounter TCNT(
    .clock(clock),
    .in(w1),
    .reset(reset),
    .out(tricount)
);

Comparator COMP(
    .in0(count),
    .in1(tricount),
    .comp_out(comp_out)
);

endmodule

Implementarea unui modul de test pentru TOP

`timescale 1ns/1ps

module TOP_TB();

reg clock_t;
reg reset_t;
reg in_t; 
wire comp_out_t;

initial begin
    clock_t = 0;
    forever #1 clock_t = ~clock_t;
end

integer idx;
	
initial begin
        reset_t = 0;
        in_t = 1;
    #2 	reset_t = 1;
        for(idx=0; idx<8; idx=idx+1) begin
            #1000  in_t = 0;
            #2     in_t = 1;
        end
    #2$stop();	
end

TOP DUT(
    .clock(clock_t),
    .reset(reset_t),
    .in(in_t),
    .comp_out(comp_out_t)
);
	
endmodule