VHDL PRACTICAL FILE
NISHANT GUPTA 064/EC/08
INTRODUCTION TO VHDL VHDL stands for VHSIC (Very High Speed Integrated Circuits) Hardware Description Language. In the mid-1980’s the U.S. Department of Defense and the IEEE sponsored the development of this hardware description language with the goal to develop very high-speed integrated circuit. It has become now one of industry’s standard languages used to describe digital systems. The other widely used hardware description language is Verilog. Both are powerful languages that allow you to describe and simulate complex digital systems. A third HDL language is ABEL (Advanced Boolean Equation Language) which was specifically designed for Programmable Logic Devices (PLD). ABEL is less powerful than the other two languages and is less popular in industry. This tutorial deals with VHDL, as described by the IEEE standard 1076-1993. Although these languages look similar as conventional programming languages, there are some important differences. A hardware description language is inherently parallel, i.e. commands, which correspond to logic gates, are executed (computed) in parallel, as soon as a new input arrives. A HDL program mimics the behavior of a physical, usually digital, system. It also allows incorporation of timing specifications (gate delays) as well as to describe a system as an interconnection of different components. VHDL allows one to describe a digital system at the structural or the behavioral level. The behavioral level can be further divided into two kinds of styles: Data flow and Algorithmic. The dataflow representation describes how data moves through the system. This is typically done in terms of data flow between registers (Register Transfer level). The data flow model makes use of concurrent statements that are executed in parallel as soon as data arrives at the input. On the other hand, sequential statements are executed in the sequence that they are specified. VHDL allows both concurrent and sequential signal assignments that will determine the manner in which they are executed. Examples of both representations will be given later.VHDL is commonly used to write text
models that describe a logic circuit. Such a model is processed by a synthesis program, only if it is part of the logic design. A simulation program is used to test the logic design using simulation models to represent the logic circuits that interface to the design. This collection of simulation models is commonly called a testbench. VHDL has file input and output capabilities, and can be used as a general-purpose language for text processing, but files are more commonly used by a simulation testbench for stimulus or verification data. There are some VHDL compilers which build executable binaries. In this case, it might be possible to use VHDL to write a testbench to verify the functionality of the design using files on the host computer to define stimuli, to interact with the user, and to compare results with those expected. However, most designers leave this job to the simulator. VHDL is not a case sensitive language. One can design hardware in a VHDL IDE (for FPGA implementation such as Xilinx ISE, Altera Quartus, or Synopsys Synplify) to produce the RTL schematic of the desired circuit. After that, the generated schematic can be verified using simulation software which shows the waveforms of inputs and outputs of the circuit after
generating the appropriate testbench. To generate an appropriate testbench for a particular circuit or VHDL code, the inputs have to be defined correctly. For example, for clock input, a loop process or an iterative statement is required. The key advantage of VHDL when used for systems design is that it allows the behavior of the required system to be described (modeled) and verified (simulated) before synthesis tools translate the design into real hardware (gates and wires). Another benefit is that VHDL allows the description of a concurrent system (many parts, each with its own sub-behaviour, working together at the same time). VHDL is a Dataflow language, unlike procedural computing languages such as BASIC, C, and assembly. VHDL is a specific type of hardware description language or HDL. There are many other examples of HDLs but the other one commonly used is called Verilog. The actual name VHDL is a acronym that stands for "VHSIC Hardware Description Language". This article contains information on the rudimentary topics that can be considered necessary to getting started with VHDL. Additionally there are code examples to illustrate the concepts covered more clearly. VHDL is a programming language, much like C++, it has its own syntax and semantics. The big difference from what is considered a traditional programing language is that instead of describing what instructions a processor will execute, it describes how circuits should be organized. As it is emulating real hardware it is inherently parallel and also treats timing as important. This language is a commonly used in the design of field-programmable gate arrays(FPGA)and application specific integrated circuits(ASIC). What hardware description languages provide is a way to run simulations, check the logic of the code, and something called logic synthesis. Logic synthesis is simply the translation of the language in to a physical circuit implementation. This allows for a much easier and less error prone hardware development process.
EXPERIMENT NO.1 Write a program to show the output of various gates (AND, OR, NOR,NOT,XOR,NAND)
entity gate is port(x,y:in BIT; outa,outb,outc,outd,oute,outf:out BIT); end entity; architecture gate_arch of gate is begin outa<=x and y; outb<=x or y; outc<=x xor y; outd<=x nor y; oute<= not x; outf<=x nand Y; end gate_arch;
entity gate_tb is end entity; architecture gate_arch_tb of gate_tb is component gate is port(x,y:in BIT; outa,outb,outc,outd,oute,outf:out BIT); end component; signal in1,in2,o1,o2,o3,o4,o5,o6:BIT; begin inst:gate port map(in1,in2,o1,o2,o3,o4,o5,o6); process begin in1<='0'; in2<='0'; wait for 100 ns; in1<='0'; in2<='1'; wait for 100 ns; in1<='1'; in2<='0'; wait for 100 ns; in1<='1'; in2<='1'; wait for 100 ns; end process; end gate_arch_tb;
EXPERIMENT NO.2 Write a program to AND two 4 BIT inputs to give a 4 BIT output entity gate_four is port(x,y:in BIT_vector(0 to 3); outa:out BIT_vector(0 to 3)); end entity; architecture arch_gate_four of gate_four is begin outa(0)<=x(0) and y(0); outa(1)<=x(1) and y(1); outa(2)<=x(2) and y(2); outa(3)<=x(3) and y(3); end arch_gate_four;
entity gate_four_tb is end entity; architecture arch_gate_four_tb of gate_four_tb is component gate_four is port(x,y:in BIT_vector(0 to 3); outa:out BIT_vector(0 to 3)); end component; signal in1,in2,o1:BIT_vector(0 to 3); begin inst:gate_four port map(in1,in2,o1); process begin in1(0)<='0'; in1(1)<='0'; in1(2)<='1'; in1(3)<='1'; in2(0)<='0'; in2(1)<='1'; in2(2)<='0'; in2(3)<='1'; wait for 100 ns; end process; end arch_gate_four_tb;
EXPERIMENT NO.3 Write a program to show the output of a half adder. Half Adder entity halfadder is port(x,y:in bit; sum,carry:out bit); end entity; architecture arch_halfadder of halfadder is begin sum<=x xor y; carry<=x and y; end arch_halfadder;
entity halfadder_tb is end entity; architecture arch_halfadder_tb of halfadder_tb is component halfadder is port(x,y:in bit; sum,carry:out bit); end component; signal in1,in2,sum,carry:bit; begin inst:halfadder port map(in1,in2,sum,carry); process begin in1<='0'; in2<='0'; wait for 100 ns; in1<='0'; in2<='1'; wait for 100 ns; in1<='1'; in2<='0'; wait for 100 ns; in1<='1'; in2<='1'; wait for 100 ns; end process; end arch_halfadder_tb;
EXPERIMENT NO.4 To construct Full Adder using Half Adder entity fulladder is port(sum, carry, z :in bit; sum0,carry0:out bit); end entity; architecture arch_fulladder of fulladder is component halfadder is port(x,y :in bit; sum,carry:out bit); end component;
begin sum0<=sum xor z; carry0<=(sum and z) or carry; end arch_fulladder;
entity fulladder_tb is end entity; architecture arch_fulladder_tb of fulladder_tb is component fulladder is port(z,sum,carry:in bit; sum0,carry0:out bit); end component; signal in1,in2,in3,sum0,carry0 :bit; begin inst:fulladder port map(in1,in2,in3,sum0,carry0); process begin in1<='0'; in2<='0'; wait for 100 ns; in1<='0'; in2<='1'; wait for 100 ns; in1<='1'; in2<='0'; wait for 100 ns; in1<='1'; in2<='1'; wait for 100 ns; end process; end arch_fulladder_tb;
EXPERIMENT NO.5 To construct 4 Bit Comparator entity compare is port(a,b: in bit_vector(3 downto 0); f1,f2,f3: out bit); end entity; architecture arch_compare of compare is begin process(a,b) begin
signal ina,inb: bit_vector(3 downto 0); signal of1,of2,of3: bit; begin inst: compare port map(ina,inb,of1,of2,of3); process begin ina <="0000"; inb <="0000";
if(a>b) then f1<='0'; f2<='0'; f3<='1';
wait for 100 ns;
elsif(a
wait for 100 ns;
else f1<='0'; f2<='1'; f3<='0'; end if; end process; end arch_compare;
wait for 100 ns;
ina<="1111"; inb<="1111";
ina<="0101"; inb<="1010";
TESTBENCH entity compare_tb is end entity; architecture arch_compare_tb of compare_tb is
component compare is port(a,b: in bit_vector(3 downto 0); f1,f2,f3: out bit); end component;
ina<="1010"; inb<="1011"; wait for 100 ns; ina<="1011"; inb<="1010"; wait for 100 ns; ina<="0010"; inb<="0011"; wait for 100 ns; end process; end arch_compare_tb;
EXPERIMENT NO.6 To construct 3X8 Decoder entity dec38 is port( a: in bit_vector(2 downto 0); b: out bit_vector(7 downto 0)); end entity; architecture arch_dec38 of dec38 is begin b(0)<= (not a(2))and (not a(1)) and (not a(0)); b(1)<= (not a(2))and (not a(1)) and (a(0)); b(2)<= (not a(2))and (a(1)) and (not a(0)); b(3)<= (not a(2))and (a(1)) and (a(0)); b(4)<= (a(2))and (not a(1)) and (not a(0)); b(5)<= (a(2))and (not a(1)) and (a(0)); b(6)<= (a(2))and (a(1)) and (not a(0)); b(7)<= (a(2))and (a(1)) and (a(0));
wait for 100 ns; inp<="000"; wait for 100 ns; inp<="001"; wait for 100 ns; inp<="010"; wait for 100 ns; inp<="011"; wait for 100 ns; inp<="100"; wait for 100 ns; inp<="101"; wait for 100 ns;
end arch_dec38;
TESTBENCH entity dec38_tb is end entity; architecture arch_dec38_tb of dec38_tb is component dec38 is port( a: in bit_vector(2 downto 0); b: out bit_vector(7 downto 0)); end component; signal inp: bit_vector(2 downto 0); signal outp:bit_vector(7 downto 0); begin inst: dec38 port map(inp,outp); process begin
inp<="110"; wait for 100 ns; inp<="111"; wait for 100 ns; inp<="101"; wait for 100 ns; end process; end arch_dec38_tb;
EXPERIMENT NO.7 To construct Full Subtractor entity subs is port(x,y,bin: in bit; diff,bout: out bit); end entity;
inx<='0'; iny<='0'; inbin<='0'; -- should be odiff-> 0, obout-> 0 wait for 100 ns;
architecture arch_subs of subs is begin -- logic relation for output pins diff<= x xor y xor bin; bout <= ((not x)and y) or (y and (not(x xor y))); end arch_subs;
inx<='0'; iny<='1'; inbin<='0'; -- should be odiff-> 1, obout-> 1 wait for 100 ns;
TESTBENCH entity subs_tb is end entity; architecture arch_subs_tb of subs_tb is component subs is port(x,y,bin: in bit; diff,bout: out bit); end component; signal inx,iny,inbin,odiff,obout: bit; begin inst: subs port map(inx,iny,inbin,odiff,obout); process begin
inx<='1'; iny<='0'; inbin<='1'; -- should be odiff-> 0, obout-> 0 wait for 100 ns; inx<='0'; iny<='1'; inbin<='1'; -- should be odiff-> 0, obout-> 1 wait for 100 ns; inx<='1'; iny<='0'; inbin<='0'; -- should be odiff-> 1, obout-> 0 wait for 100 ns; inx<='1'; iny<='1'; inbin<='1'; -- should be odiff-> 1, obout-> 1 wait for 100 ns; end process; end arch_subs_tb;
EXPERIMENT NO.8 To construct D, T and JK Flip Flop D Flip Flop entity dff is port (d,clk: in bit; q: out bit); end entity; architecture arch_dff of dff is begin process(clk) begin if(clk'event and clk='1') then q <= d; end if; end process; end arch_dff;
TESTBENCH entity dff_tb is end entity; architecture arch_dff_tb of dff_tb is component dff is port (d,clk: in bit; q: out bit); end component; signal d1,clk,q1: bit; constant clk_period:time:=50 ns; begin inst: dff port map (d1,clk,q1);
clk_process:process begin clk<='0'; wait for clk_period/2; clk<='1'; wait for clk_period/2; end process; stim_process:process begin d1<='0'; wait for clk_period*2; d1<='1'; wait for clk_period*2; d1<='0'; wait for clk_period*2; d1<='1'; wait for clk_period*2; end process; end arch_dff_tb;
D Flip Flop
EXPERIMENT NO. 9 To construct 8-Bit Shift Register Include dff.vhdl in the workspace.
entity shift8 is port(dd,clka: in bit; oo: out bit); end shift8; architecture arch_shift8 of shift8 is signal output: bit_vector(6 downto 0):="0000000"; component dff is port (d,clk: in bit; q: out bit); end component; begin d0: dff port map(dd,clka,output(0)); d1: dff port map(output(0),clka,output(1)); d2: dff port map(output(1),clka,output(2)); d3: dff port map(output(2),clka,output(3)); d4: dff port map(output(3),clka,output(4)); d5: dff port map(output(4),clka,output(5)); d6: dff port map(output(5),clka,output(6)); d7: dff port map(output(6),clka,oo); end arch_shift8;
TESTBENCH entity shift8_tb is end entity; architecture arch_shift8_tb of shift8_tb is component shift8 is port(dd,clka: in bit; oo: out bit); end component; signal outp,inp,clk: bit; constant clk_period: time:= 50 ns;
begin inst: shift8 port map(inp,clk,outp); clk_process:process begin clk<='0'; wait for clk_period/2; clk<='1'; wait for clk_period/2; end process; stim_process:process begin inp<='1'; wait for clk_period; inp<='0'; wait for clk_period; inp<='1'; wait for clk_period; inp<='0'; wait for clk_period; inp<='1'; wait for clk_period; inp<='0'; wait for clk_period; inp<='1'; wait for clk_period; end process; end arch_shift8_tb;