CID Aplicatii 13

De la WikiLabs
Jump to navigationJump to search
Versiunea pentru tipărire nu mai este suportată și poate avea erori de randare. Vă rugăm să vă actualizați bookmarkurile browserului și să folosiți funcția implicită de tipărire a browserului.

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:

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:

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:

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