Showing posts with label vhdl. Show all posts
Showing posts with label vhdl. Show all posts

1101 sequence detector state diagram with VHDL code

A sequence detector is good example of sequential logic circuit also called FSM(Finite State Machine). A 1101 sequence detector detects 1101 consecutive bits in a string of binary bits. It is good practice to draw the state diagram of the sequence of process that happens to capture understanding of the behavior of the circuit. In the design of 1101 sequence detector, the design of state diagram is the first step, which then is followed by the creation of state table, state transition table and finally the circuit itself and testing being the final step.

Readers are recommended to read the following posts which are related to this blog post. A detailed steps to construct a sequential circuit is provided in the blog post- How to design Sequence Detector in 10 easy steps. Also another post useful in sequential circuit is- how to design Moore sequential circuit in Simulink. And futhermore this post- how to use Xilinx Schematic editor with example of sequence detector shows how xilinx software can be used to design and verify the sequence detector.

The state diagram of 1101 sequence detector is shown below-


State S1:
 Beginning at state S1 when 0 is received it stays in the same state because it has nothing to remember and the output is 0 because the sequence 1101 is not detected. Only at the instant when 1101 sequence is detected the output is high, that is, 1. Also remember that the flip flops should be used when things are to be remembered by the circuit. When 1 arrives when in state S1, then it goes to next state S2 and it remembers that 1 was received which is part of the sequence 1101 which is to be detected.

State S2:
When in state S2, when 1 arrives, since it is part of the sequence it goes to next state S3, meaning it remembers 1. When 0 is received it cannot go to next state S3(since 1 received has occupied the transition condition and because 0 is not part of the sequence and there is nothing to remember), and it cannot remain in the same state S2 because this would mean 010 indefinite loop while in state S2, therefore it goes back to the initial state S1. Consider 100 is received and machine remains in S2 when 0 is received, then because of 1 the state changes from S1 to S2, then 0 is received then the machine stays in S2 and when another 0 is received then it stays again in S2. But consider when 100 is received and machine goes back to S1, then when 1 is received it changes state from S1 to S2, when 0 is received then goes back to S1 and when another 0 is received it stays in S1.

State S3:
When in state S3, when 0 is received then since it is part of the sequence 1101 it goes to new state S4 because the machine has to remember the new bit 0 as part of the sequence detection algorithm. When 1 is received it stays in the same state.

State S4:
When in state S4, when 1 is received then since it is part of the sequence 1101 to be detected it goes to S2. And when 0 is received then it goes back to initial state S1. At this point the machine outputs 1.

Following is a simulated digital waveform for the seqence 10101101010110001


The graph shows that the output z is high when 1101 is detected in the sequence x = 10101101010110001

The VHDL code for implementing this sequence detector is below-

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

entity sequence_detector is
port (
clk: in STD_LOGIC;
rst: in STD_LOGIC;
x: in STD_LOGIC;
z: out STD_LOGIC);
end sequence_detector;

architecture sequence_detector_arch of sequence_detector is

type seq_detect_type is (
    S1, S2, S3, S4
);

signal seq_detect: seq_detect_type;

begin

seq_detect_machine: process (clk)
begin
if clkevent and clk = 1 then
if rst=1 then
seq_detect <= S1;

else

case seq_detect is
when S1 =>
if x = 1 then
seq_detect <= S2;
elsif x = 0 then
seq_detect <= S1;
end if;
when S2 =>
if x = 1 then
seq_detect <= S3;
elsif x = 0 then
seq_detect <= S1;
end if;
when S3 =>
if x = 1 then
seq_detect <= S3;
elsif x = 0 then
seq_detect <= S4;
end if;
when S4 =>
if x = 1 then
seq_detect <= S2;
elsif x = 0 then
seq_detect <= S1;
end if;

when others =>
null;

end case;
end if;
end if;
end process;

z_assignment:
z <= 0 when (seq_detect = S1 and x = 1) else
     0 when (seq_detect = S1 and (x = 0 and not (x = 1))) else
     0 when (seq_detect = S2 and x = 1) else
     0 when (seq_detect = S2 and (x = 0 and not (x = 1))) else
     0 when (seq_detect = S3 and x = 1) else
     0 when (seq_detect = S3 and (x = 0 and not (x = 1))) else
     1 when (seq_detect = S4 and x = 1) else
     0 when (seq_detect = S4 and (x = 0 and not (x = 1))) else
     0;

end sequence_detector_arch;

The testbench code for the sequence detector is,

library ieee;
use ieee.STD_LOGIC_UNSIGNED.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity sequence_detector_tb is
end sequence_detector_tb;

architecture TB_ARCHITECTURE of sequence_detector_tb is

component sequence_detector
port(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
x : in STD_LOGIC;
z : out STD_LOGIC );
end component;

signal clk : STD_LOGIC;
signal rst : STD_LOGIC;
signal x : STD_LOGIC;
signal z : STD_LOGIC;

begin

UUT : sequence_detector
port map (
clk => clk,
rst => rst,
x => x,
z => z
);

clk_process : process
begin
clk <= 0;
wait for 5 ns;

clk <= 1;
wait for 5 ns;

end process;

sti_process: process
begin
x <= 0;
wait for 10 ns;

x <= 0;
wait for 10 ns;

x <= 1;
wait for 10 ns;

x <= 0;
wait for 10 ns;

x <= 1;
wait for 10 ns;

x <= 0;
wait for 10 ns;

x <= 1;
wait for 10 ns;

x <= 1;
wait for 10 ns;

x <= 0;
wait for 10 ns;

x <= 1;
wait for 10 ns;

x <= 0;
wait for 10 ns;

x <= 1;
wait for 10 ns;

x <= 0;
wait for 10 ns;

x <= 1;
wait for 10 ns;

x <= 1;
wait for 10 ns;

x <= 0;
wait for 10 ns;

end process;

end TB_ARCHITECTURE;

configuration TESTBENCH_FOR_sequence_detector of sequence_detector_tb is
for TB_ARCHITECTURE
for UUT : sequence_detector
use entity work.sequence_detector(sequence_detector_arch);
end for;
end for;
end TESTBENCH_FOR_sequence_detector;
Read More..

Flash ADC priority encoder vhdl design

The priority encoder is useful in many application not only in digital circuit but also in the mixed circuit such as analog to digital converter(ADC). For example Flash type ADC uses priority encoder to select which of the different inputs should be sampled and encoded into digital digital bits. The following shows how Flash type ADC works first then VHDL model for the priority encoder is developed.

There are different types of ADC and one of them is Parallel Comparator ADC or Flash ADC. The Flash ADC converts analog signal to digital signal very fast compared to other types of ADC such as Dual Slope ADC or Successive Approximation Register(SAR) ADC. That is its conversion time is small. The disadvantage of Flash ADC is that if the resolution is to be increased then the number of comparator has to be increased which makes the converter bulky.

The Flash ADC can be described as being composed of 3 different constituents- the Voltage Divider Resistor(VDR) network, the Comparators(op-amp) and the priority encoder.

The VDR network is used to create voltage reference with which the input analog signal is compared using the comparator. The voltage reference points is created using same value resistor and the number of the reference points to be created is decided by the number of digital bits one wants to produce. As an example, if n=3 bits is used for the digital signal output then the number of the voltage reference point is 2^3-1= 7. Next the input analog signal which is to be converted into digital signal is done by fedding the analog signal to the inputs of the comparators. The analog signal is fed into the non-inverting terminal of the op-amp and the voltage references are connected to the inverting terminal of the op-amp. The output of those op-amp becomes high in which the input signal voltage is greater than the reference voltage. If there are 7 op-amps comparator, then the analog signal voltage becomes greater than the reference voltage starting from the 3rd op-amp then the rest of the op-amp output also becomes high. That is the 3rd, 4th, 5th, 6th and 7th op-amp output are high.

The priority encoder gives priority to that op-amp output which is first activated high, in this case the 3rd op-amp. Then the priority encoder outputs digital bits corresponding to the digit 5.

Thus one use of priority encoder is in the ADC converter. Now the following describes how a priority encoder is modelled in VHDL.



The input to the priority encoder for the 3 bits digital signal output from the ADC are the 7 outputs from the comparator(op-amps). Depending upon which output gets activated first we produce corresponding digital outputs.

Let Cinp be the input to the priority encoder and Dcode be the digital codes. Then the entity declaration of this priority encoder becomes-

entity priority_encoder is
    port(
    Cinp : in std_logic_vector(7 downto 0);
    Dcode : out std_logic_vector(2 downto 0)
    );
end priority_encoder;

Next we need to create the architecture for the priority encoder. The following is the VHDL code for the flash type ADC priority encoder:

architecture priority_encoder_arch of priority_encoder is
begin
Dcode <= "111" when (Cinp(7)=1) else
"110" when (Cinp(6)=1) else
"101" when (Cinp(5)=1) else
"100" when (Cinp(4)=1) else
"011" when (Cinp(3)=1) else
"010" when (Cinp(2)=1) else
"001" when (Cinp(1)=1) else
"000"; 
end priority_encoder_arch;
Read More..

How to design a code converter using VHDL

Code converter finds application in digital system design and in this blog it is shown how to design a code converter using VHDL. There are many instances that requires code conversion for example in communication system encoding. For example binary to excess 3 code or binary to gray code or gray code to excess 3 code.

The conversion of codes from one to another can be done in different ways. One way is to construct state diagram. Another way is simply to use case statements or if-then-elsif or select statements. There may be also other ways.

Here it is shown how case statement and select statement can be using to convert binary code to excess 3 code.

The first thing to know is what and how they need to converted. 4bit excess 3 code is obtained by adding 0011 to the 4 bit binary value.

It is helpful to construct a truth table for the conversion.


There are 16 codes listed above, but here only 8 codes will be illustrated as this is enough to illustrate how to implement the conversion.

Let x and y be the input and output respectively, that is x is the binary 4 bit input and y is the 4 bit excess 3 code output.

So the entity declaration would look this,

entity code_converter is
    port(
    x : in std_logic_vector(3 downto 0);
    y : out std_logic_vector(3 downto 0)
    )
end code_converter;

Now to the question of How to design a code converter using VHDL?

First it is shown how select statement can be used to do the code conversion. The architecture for the code converter using the select statment is as follows,

architecture Select_RTL of code_converter is

begin
        with x select
        y <= "0011" when "0000",
        "0100" when "0001",
        "0101" when "0010",
        "0110" when "0011",
        "0111" when "0100",
        "1000" when "0101",
        "1001" when "0110",
        "1010"    when "0111",
        "XXXX" when others;
               
end Select_RTL;

Now the same code conversion can be achieved using case statement as follows,

architecture Case_RTL of code_converter is

begin
    process (x)
    begin
        case x is
            when "0000" => y <= "0011";
            when "0001"    => y <= "0100";
            when "0010"    => y <= "0101";
            when "0011" => y <= "0110";
            when "0100" => y <= "0111";
            when "0101" => y <= "1000";
            when "0110" => y <= "1001";
            when "0111" => y <= "1010";
            when others => y <= "XXXX";
        end case;
       
    end process;
end Case_RTL;

Yet there is another method that can be used to implement this conversion. It is much simpler than the above two methods.

architecture add_RTL of code_converter is

signal y_int : integer;

begin
    y_int <= to_integer(unsigned(x)) + 3;
    y <= std_logic_vector(to_unsigned(y_int,4));

end add_RTL;

In this method, the input binary x was converted to integer and 3 was added to it. The result was converted back to binary bits.

See the tutorial- http://appliedelectronicsengineering.blogspot.com/2014/10/how-to-convert-stdlogicvector-to.html to see how to convert between different data types.

So in this way we can use different methods to design a code converted using VHDL.
Read More..