Wednesday, February 29, 2012

Dual Priority Encoder VHDL code (A dual-priority encoder returns the codes of the highest and second-highest priority requests)

Project specification:
A dual-priority encoder returns the codes of the highest and second-highest priority requests.
The input is the 10-bit r signal, in which the r(10) has the highest priority and r(1) has the lowest
priority. The outputs are fst and snd, which are the 4-bit binary codes of the highest and secondhighest
priority requests, respectively. The input and output signals are
   input:
r: 10-bit input request

   output:
fst: 4-bit output, the binary code of the highest priority request
snd: 4-bit output, the binary code of the second-highest priority request


Design Procedures:
   1. Encoder circuit
The best way to derive efficient VHDL code is to think in terms of hardware. First, draw a
conceptual top-level schematic diagram (i.e., what you will do if no HDL/synthesis software is
available) and then derive the code accordingly.


   2. Testing circuit with 7-segment display
Use 10-bit switch as the request signal. Decode the fst and snd signals and display the two
codes in hex format in two seven-segment LED displays.


   3. Implementation with truth table
A combination circuit can be exhaustively specified by a truth table, which can be realized by
one VHDL selected assignment statement. For the 10-request dual-priority encoder in this
experiment, a 210-by-8 table is needed. The architecture body looks like
architecture table_arch of dual_prio is
signal both: std_logic_vector(7 downto 0); -- codes of 1st & 2nd
begin
with r select
both <=
"00000000" when "0000000000", -- 1st:0; 2nd:0
"00010000" when "0000000001", -- 1st:1; 2nd:0
"00100000" when "0000000010", -- 1st:2; 2nd:0
"00100001" when "0000000011", -- 1st:2; 2nd:1
... -- 1024 lines
fst <= both(7 downto 4);
snd <= both(3 downto 0);
end table_arch;
While the code is straightforward, manually completing the 1024 rows is tedious and time
consuming. If you wish, you can write a program in the language of your choice (C, Java, Perl,
etc.) to generate theses rows and copy/paste them to the VHDL code.

Priority encode VHDL code:

library ieee;
use ieee.std_logic_1164.all;
entity prio_encoder is
port
(
p: in std_logic_vector(10 downto 1);
pcode: out std_logic_vector(3 downto 0)
);
end prio_encoder;
architecture encode of prio_encoder is
begin
process(p)
begin
if (p(10)='1') then
pcode <= "1010";
elsif (p(9)='1')then
pcode <= "1001";
elsif (p(8)='1')then
pcode <= "1000";
elsif (p(7)='1')then
pcode <= "0111";
elsif (p(6)='1')then
pcode <= "0110";
elsif (p(5)='1')then
pcode <= "0101";
elsif (p(4)='1')then
pcode <= "0100";
elsif (p(3)='1')then
pcode <= "0011";
elsif (p(2)='1')then
pcode <= "0010";
elsif (p(1)='1')then
pcode <= "0001";
else
pcode <= "0000";
end if;
end process;
end encode;

4 to 10 bit Decoder VHDL code:

library ieee;
use ieee.std_logic_1164.all;
entity decoder_4_10 is
   port(
      x: in std_logic_vector(3 downto 0);
      y: out std_logic_vector(10 downto 1)
   );
end decoder_4_10;
architecture if_arch of decoder_4_10 is begin
   process(x)
   begin
      if (x="1010") then
         y <= "1000000000";
      elsif (x="1001")then
         y <= "0100000000";
      elsif (x="1000")then
         y <= "0010000000";
      elsif (x="0111")then
         y <= "0001000000";
      elsif (x="0110")then
         y <= "0000100000";
      elsif (x="0101")then
         y <= "0000010000";
      elsif (x="0100")then
         y <= "0000001000";
      elsif (x="0011")then
         y <= "0000000100";
      elsif (x="0010")then
         y <= "0000000010";
      elsif (x="0001")then
         y <= "0000000001";
      else
y <= "0000000000";
      end if;
   end process;
end if_arch;


Dual priority bit checker VHDL code:

use ieee.std_logic_1164.all;
entity dual_prio is
 port
 (
r: in std_logic_vector(9 downto 0);
fst, snd: out std_logic_vector(3 downto 0);
hex0, hex1: out std_logic_vector(6 downto 0)
 );
end dual_prio;
architecture func_dual_prio of dual_prio is
--signal p: std_logic_vector(10 downto 1);
signal q: std_logic_vector(3 downto 0);
signal s: std_logic_vector(3 downto 0);
--signal m: std_logic_vector(3 downto 0);
signal n: std_logic_vector(10 downto 1);
signal z: std_logic_vector(10 downto 1);
begin
prio1_unit: entity work.prio_encoder(encode)
      port map(p=>r, pcode=>q);
fst <= q;
hex1_unit: entity work.hex_toshow_LES(arch)
      port map(bin=>q, sseg=>hex1);
deco1_unit: entity work.decoder_4_10(if_arch)
      port map(x=>q, y=>n);
z <= (not n) and r;
prio2_unit: entity work.prio_encoder(encode)
      port map(p=>z, pcode=>s);
snd <= s;
hex0_unit: entity work.hex_toshow_LES(arch)
      port map(bin=>s, sseg=>hex0);
end func_dual_prio;

LED hexes to show LES VHDL code:
library ieee;
use ieee.std_logic_1164.all;
entity hex_toshow_LES is
   port(
      bin: in std_logic_vector(3 downto 0);
      sseg: out std_logic_vector(6 downto 0)
   );
end hex_toshow_LES;
architecture arch of hex_toshow_LES is
begin
with bin select
         sseg <=
"1000000" when "0000",
"1111001" when "0001",
"0100100" when "0010",
"0110000" when "0011",
"0011001" when "0100",
"0010010" when "0101",
"0000010" when "0110",
"1111000" when "0111",
"0000000" when "1000",
"0010000" when "1001",
"0001000" when "1010",
"0000011" when "1011",
"1000110" when "1100",
"0100001" when "1101",
"0000110" when "1110",
"0001110" when others;
end arch; 

0 comments:

Post a Comment