From 996064bcdc3c1733c6b718f9a6cdff576b20b75e Mon Sep 17 00:00:00 2001 From: antoniovillena Date: Sun, 11 Dec 2016 19:36:59 +0100 Subject: [PATCH] =?UTF-8?q?A=C3=B1ado=20ch03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cores/curso/cap1/clock7.vhd | 60 --------------- cores/curso/cap1/colenc.vhd | 28 ------- cores/curso/cap1/main.prj | 3 - cores/curso/cap1/main.vhd | 62 ---------------- cores/curso/cap1/make.bat | 9 --- cores/curso/cap1/pines_zxuno_v4.ucf | 12 --- cores/curso/ch01/list_ch01_01_eq1.vhd | 19 +++++ cores/curso/ch01/list_ch01_02_03_04_eq2.vhd | 57 +++++++++++++++ cores/curso/ch01/list_ch01_05_tb.vhd | 50 +++++++++++++ cores/curso/ch02/list_ch02_01_eq1.vhd | 19 +++++ cores/curso/ch02/list_ch02_02_eq2.vhd | 21 ++++++ cores/curso/ch02/list_ch02_03_tb.vhd | 49 +++++++++++++ cores/curso/ch03/ch03_zxuno_v4.ucf | 52 +++++++++++++ cores/curso/ch03/disp_mux.vhd | 55 ++++++++++++++ cores/curso/ch03/hex_to_sseg.vhd | 31 ++++++++ cores/curso/ch03/hex_to_sseg_test.prj | 3 + .../main.ut => ch03/hex_to_sseg_test.ut} | 0 cores/curso/ch03/hex_to_sseg_test.xst | 53 ++++++++++++++ .../curso/ch03/list_ch03_01_03_05_07_prio.vhd | 71 ++++++++++++++++++ .../ch03/list_ch03_02_04_06_08_decode.vhd | 73 +++++++++++++++++++ cores/curso/ch03/list_ch03_09_10_add.vhd | 33 +++++++++ cores/curso/ch03/list_ch03_11_gen_add.vhd | 22 ++++++ cores/curso/ch03/list_ch03_12_hex2led.vhd | 33 +++++++++ cores/curso/ch03/list_ch03_13_led_test.vhd | 47 ++++++++++++ cores/curso/ch03/list_ch03_14_smadd.vhd | 40 ++++++++++ cores/curso/ch03/list_ch03_15_smadd_test.vhd | 55 ++++++++++++++ cores/curso/ch03/make.bat | 10 +++ cores/curso/ch03/sm_add_test.prj | 4 + cores/curso/ch03/sm_add_test.ut | 31 ++++++++ .../{cap1/main.xst => ch03/sm_add_test.xst} | 6 +- cores/curso/ch03/timings.xcf | 2 + 31 files changed, 833 insertions(+), 177 deletions(-) delete mode 100644 cores/curso/cap1/clock7.vhd delete mode 100644 cores/curso/cap1/colenc.vhd delete mode 100644 cores/curso/cap1/main.prj delete mode 100644 cores/curso/cap1/main.vhd delete mode 100644 cores/curso/cap1/make.bat delete mode 100644 cores/curso/cap1/pines_zxuno_v4.ucf create mode 100644 cores/curso/ch01/list_ch01_01_eq1.vhd create mode 100644 cores/curso/ch01/list_ch01_02_03_04_eq2.vhd create mode 100644 cores/curso/ch01/list_ch01_05_tb.vhd create mode 100644 cores/curso/ch02/list_ch02_01_eq1.vhd create mode 100644 cores/curso/ch02/list_ch02_02_eq2.vhd create mode 100644 cores/curso/ch02/list_ch02_03_tb.vhd create mode 100644 cores/curso/ch03/ch03_zxuno_v4.ucf create mode 100644 cores/curso/ch03/disp_mux.vhd create mode 100644 cores/curso/ch03/hex_to_sseg.vhd create mode 100644 cores/curso/ch03/hex_to_sseg_test.prj rename cores/curso/{cap1/main.ut => ch03/hex_to_sseg_test.ut} (100%) create mode 100644 cores/curso/ch03/hex_to_sseg_test.xst create mode 100644 cores/curso/ch03/list_ch03_01_03_05_07_prio.vhd create mode 100644 cores/curso/ch03/list_ch03_02_04_06_08_decode.vhd create mode 100644 cores/curso/ch03/list_ch03_09_10_add.vhd create mode 100644 cores/curso/ch03/list_ch03_11_gen_add.vhd create mode 100644 cores/curso/ch03/list_ch03_12_hex2led.vhd create mode 100644 cores/curso/ch03/list_ch03_13_led_test.vhd create mode 100644 cores/curso/ch03/list_ch03_14_smadd.vhd create mode 100644 cores/curso/ch03/list_ch03_15_smadd_test.vhd create mode 100644 cores/curso/ch03/make.bat create mode 100644 cores/curso/ch03/sm_add_test.prj create mode 100644 cores/curso/ch03/sm_add_test.ut rename cores/curso/{cap1/main.xst => ch03/sm_add_test.xst} (94%) create mode 100644 cores/curso/ch03/timings.xcf diff --git a/cores/curso/cap1/clock7.vhd b/cores/curso/cap1/clock7.vhd deleted file mode 100644 index 4ed4584..0000000 --- a/cores/curso/cap1/clock7.vhd +++ /dev/null @@ -1,60 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -library unisim; -use unisim.vcomponents.all; - -entity clock7 is - port( clkin_in : in std_logic; - clkfx_out : out std_logic); -end clock7; - -architecture behavioral of clock7 is - - signal clkfb_in : std_logic; - signal clkfx_buf: std_logic; - signal clk0_buf : std_logic; - signal gnd_bit : std_logic; - -begin - gnd_bit <= '0'; - clkfx_bufg_inst : bufg - port map( i => clkfx_buf, - o => clkfx_out); - clk0_bufg_inst : bufg - port map( i => clk0_buf, - o => clkfb_in); - dcm_sp_inst : dcm_sp - generic map ( clk_feedback => "1X", - clkdv_divide => 2.0, - clkfx_divide => 25, - clkfx_multiply => 7, - clkin_divide_by_2 => true, - clkin_period => 20.0, - clkout_phase_shift => "NONE", - deskew_adjust => "SYSTEM_SYNCHRONOUS", - dfs_frequency_mode => "LOW", - dll_frequency_mode => "LOW", - duty_cycle_correction => true, - factory_jf => x"C080", - phase_shift => 0, - startup_wait => false) - port map( clkfb => clkfb_in, - clkin => clkin_in, - dssen => gnd_bit, - psclk => gnd_bit, - psen => gnd_bit, - psincdec=> gnd_bit, - rst => gnd_bit, - clkdv => open, - clkfx => clkfx_buf, - clkfx180=> open, - clk0 => clk0_buf, - clk2x => open, - clk2x180=> open, - clk90 => open, - clk180 => open, - clk270 => open, - locked => open, - psdone => open, - status => open); -end behavioral; diff --git a/cores/curso/cap1/colenc.vhd b/cores/curso/cap1/colenc.vhd deleted file mode 100644 index 4e483af..0000000 --- a/cores/curso/cap1/colenc.vhd +++ /dev/null @@ -1,28 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; - -entity colenc is - port ( clk_in : in std_logic; - col_in : in std_logic_vector (3 downto 0); - r_out : out std_logic_vector (2 downto 0); - g_out : out std_logic_vector (2 downto 0); - b_out : out std_logic_vector (2 downto 0)); -end colenc; - -architecture behavioral of colenc is -begin - process (clk_in) - begin - if rising_edge( clk_in ) then - if( col_in(3)='0' ) then - g_out<= col_in(2) & '0' & col_in(2); - r_out<= col_in(1) & '0' & col_in(1); - b_out<= col_in(0) & '0' & col_in(0); - else - g_out<= col_in(2) & col_in(2) & col_in(2); - r_out<= col_in(1) & col_in(1) & col_in(1); - b_out<= col_in(0) & col_in(0) & col_in(0); - end if; - end if; - end process; -end behavioral; diff --git a/cores/curso/cap1/main.prj b/cores/curso/cap1/main.prj deleted file mode 100644 index 9d863ea..0000000 --- a/cores/curso/cap1/main.prj +++ /dev/null @@ -1,3 +0,0 @@ -vhdl work "clock7.vhd" -vhdl work "colenc.vhd" -vhdl work "main.vhd" diff --git a/cores/curso/cap1/main.vhd b/cores/curso/cap1/main.vhd deleted file mode 100644 index 07fb1eb..0000000 --- a/cores/curso/cap1/main.vhd +++ /dev/null @@ -1,62 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity main is port( - clk50 : in std_logic; - sync : out std_logic; - pal : out std_logic; - r : out std_logic_vector (2 downto 0); - g : out std_logic_vector (2 downto 0); - b : out std_logic_vector (2 downto 0)); -end main; - -architecture behavioral of main is - - signal clk7 : std_logic; - signal hcount : unsigned (8 downto 0); - signal vcount : unsigned (8 downto 0); - signal color : std_logic_vector (3 downto 0); - -begin - clock7_inst: entity work.clock7 port map ( - clkin_in => clk50, - clkfx_out => clk7); - - colenc_inst: entity work.colenc port map ( - clk_in => clk7, - col_in => color, - r_out => r, - g_out => g, - b_out => b); - - process (clk7) - begin - sync <= '0'; - color <= "0000"; - if rising_edge( clk7 ) then - if hcount=447 then - hcount <= (others => '0'); - if vcount=311 then - vcount <= (others => '0'); - else - vcount <= vcount + 1; - end if; - else - hcount <= hcount + 1; - end if; - if ( vcount<248 or vcount>=252 ) and - ( hcount<344-8 or hcount>=376-8) then - sync <= '1'; - if hcount<256 and vcount<192 then - color <= std_logic_vector(hcount(7 downto 4)); - elsif hcount<320-8 or hcount>=416-8 then - color <= "0111"; - end if; - end if; - end if; - end process; - - pal <= '1'; - -end behavioral; diff --git a/cores/curso/cap1/make.bat b/cores/curso/cap1/make.bat deleted file mode 100644 index 8ab43d9..0000000 --- a/cores/curso/cap1/make.bat +++ /dev/null @@ -1,9 +0,0 @@ -SET machine=main -SET speed=2 -SET ruta_ucf=pines -SET ruta_bat=..\..\ -call %ruta_bat%genxst.bat -rem call %ruta_bat%generar.bat v2 -rem call %ruta_bat%generar.bat v3 -call %ruta_bat%generar.bat v4 -rem call %ruta_bat%generar.bat Ap diff --git a/cores/curso/cap1/pines_zxuno_v4.ucf b/cores/curso/cap1/pines_zxuno_v4.ucf deleted file mode 100644 index dc260e2..0000000 --- a/cores/curso/cap1/pines_zxuno_v4.ucf +++ /dev/null @@ -1,12 +0,0 @@ -NET "clk50" LOC="P55" | IOSTANDARD = LVCMOS33; -NET "r<2>" LOC="P81" | IOSTANDARD = LVCMOS33; -NET "r<1>" LOC="P80" | IOSTANDARD = LVCMOS33; -NET "r<0>" LOC="P79" | IOSTANDARD = LVCMOS33; -NET "g<2>" LOC="P84" | IOSTANDARD = LVCMOS33; -NET "g<1>" LOC="P83" | IOSTANDARD = LVCMOS33; -NET "g<0>" LOC="P82" | IOSTANDARD = LVCMOS33; -NET "b<2>" LOC="P93" | IOSTANDARD = LVCMOS33; -NET "b<1>" LOC="P92" | IOSTANDARD = LVCMOS33; -NET "b<0>" LOC="P88" | IOSTANDARD = LVCMOS33; -NET "sync" LOC="P87" | IOSTANDARD = LVCMOS33; -NET "pal" LOC="P67" | IOSTANDARD = LVCMOS33; diff --git a/cores/curso/ch01/list_ch01_01_eq1.vhd b/cores/curso/ch01/list_ch01_01_eq1.vhd new file mode 100644 index 0000000..edb3fff --- /dev/null +++ b/cores/curso/ch01/list_ch01_01_eq1.vhd @@ -0,0 +1,19 @@ +-- Listing 1.1 +library ieee; +use ieee.std_logic_1164.all; +entity eq1 is + port( + i0, i1: in std_logic; + eq: out std_logic + ); +end eq1; + +architecture sop_arch of eq1 is + signal p0, p1: std_logic; +begin + -- sum of two product terms + eq <= p0 or p1; + -- product terms + p0 <= (not i0) and (not i1); + p1 <= i0 and i1; +end sop_arch; \ No newline at end of file diff --git a/cores/curso/ch01/list_ch01_02_03_04_eq2.vhd b/cores/curso/ch01/list_ch01_02_03_04_eq2.vhd new file mode 100644 index 0000000..99452eb --- /dev/null +++ b/cores/curso/ch01/list_ch01_02_03_04_eq2.vhd @@ -0,0 +1,57 @@ +-- Listing 1.2 +library ieee; +use ieee.std_logic_1164.all; +entity eq2 is + port( + a, b: in std_logic_vector(1 downto 0); + aeqb: out std_logic + ); +end eq2; + +architecture sop_arch of eq2 is + signal p0,p1,p2,p3: std_logic; +begin + -- sum of product terms + aeqb <= p0 or p1 or p2 or p3; + -- product terms + p0 <= ((not a(1)) and (not b(1))) and + ((not a(0)) and (not b(0))); + p1 <= ((not a(1)) and (not b(1))) and (a(0) and b(0)); + p2 <= (a(1) and b(1)) and ((not a(0)) and (not b(0))); + p3 <= (a(1) and b(1)) and (a(0) and b(0)); +end sop_arch; + + +-- Listing 1.3 +architecture struc_arch of eq2 is + signal e0, e1: std_logic; +begin + -- instantiate two 1-bit comparators + eq_bit0_unit: entity work.eq1(sop_arch) + port map(i0=>a(0), i1=>b(0), eq=>e0); + eq_bit1_unit: entity work.eq1(sop_arch) + port map(i0=>a(1), i1=>b(1), eq=>e1); + -- a and b are equal if individual bits are equal + aeqb <= e0 and e1; +end struc_arch; + + +-- Listing 1.4 +architecture vhd_87_arch of eq2 is + -- component declaration + component eq1 + port( + i0, i1: in std_logic; + eq: out std_logic + ); + end component; + signal e0, e1: std_logic; +begin + -- instantiate two 1-bit comparators + eq_bit0_unit: eq1 -- use the declared name, eq1 + port map(i0=>a(0), i1=>b(0), eq=>e0); + eq_bit1_unit: eq1 -- use the declared name, eq1 + port map(i0=>a(1), i1=>b(1), eq=>e1); + -- a and b are equal if individual bits are equal + aeqb <= e0 and e1; +end vhd_87_arch; diff --git a/cores/curso/ch01/list_ch01_05_tb.vhd b/cores/curso/ch01/list_ch01_05_tb.vhd new file mode 100644 index 0000000..aef2999 --- /dev/null +++ b/cores/curso/ch01/list_ch01_05_tb.vhd @@ -0,0 +1,50 @@ +-- Listing 1.5 +library ieee; +use ieee.std_logic_1164.all; +entity eq2_testbench is +end eq2_testbench; + +architecture tb_arch of eq2_testbench is + signal test_in0, test_in1: std_logic_vector(1 downto 0); + signal test_out: std_logic; +begin + -- instantiate the circuit under test + uut: entity work.eq2(struc_arch) + port map(a=>test_in0, b=>test_in1, aeqb=>test_out); + -- test vector generator + process + begin + -- test vector 1 + test_in0 <= "00"; + test_in1 <= "00"; + wait for 200 ns; + -- test vector 2 + test_in0 <= "01"; + test_in1 <= "00"; + wait for 200 ns; + -- test vector 3 + test_in0 <= "01"; + test_in1 <= "11"; + wait for 200 ns; + -- test vector 4 + test_in0 <= "10"; + test_in1 <= "10"; + wait for 200 ns; + -- test vector 5 + test_in0 <= "10"; + test_in1 <= "00"; + wait for 200 ns; + -- test vector 6 + test_in0 <= "11"; + test_in1 <= "11"; + wait for 200 ns; + -- test vector 7 + test_in0 <= "11"; + test_in1 <= "01"; + wait for 200 ns; + -- terminate simulation + assert false + report "Simulation Completed" + severity failure; + end process; +end tb_arch; \ No newline at end of file diff --git a/cores/curso/ch02/list_ch02_01_eq1.vhd b/cores/curso/ch02/list_ch02_01_eq1.vhd new file mode 100644 index 0000000..a4317f7 --- /dev/null +++ b/cores/curso/ch02/list_ch02_01_eq1.vhd @@ -0,0 +1,19 @@ +-- Listing 2.1 +library ieee; +use ieee.std_logic_1164.all; +entity eq1 is + port( + i0, i1: in std_logic; + eq: out std_logic + ); +end eq1; + +architecture sop_arch of eq1 is + signal p0, p1: std_logic; +begin + -- sum of two product terms + eq <= p0 or p1; + -- product terms + p0 <= (not i0) and (not i1); + p1 <= i0 and i1; +end sop_arch; \ No newline at end of file diff --git a/cores/curso/ch02/list_ch02_02_eq2.vhd b/cores/curso/ch02/list_ch02_02_eq2.vhd new file mode 100644 index 0000000..37c6262 --- /dev/null +++ b/cores/curso/ch02/list_ch02_02_eq2.vhd @@ -0,0 +1,21 @@ +-- Listing 2.2 +library ieee; +use ieee.std_logic_1164.all; +entity eq2 is + port( + a, b: in std_logic_vector(1 downto 0); + aeqb: out std_logic + ); +end eq2; + +architecture struc_arch of eq2 is + signal e0, e1: std_logic; +begin + -- instantiate two 1-bit comparators + eq_bit0_unit: entity work.eq1(sop_arch) + port map(i0=>a(0), i1=>b(0), eq=>e0); + eq_bit1_unit: entity work.eq1(sop_arch) + port map(i0=>a(1), i1=>b(1), eq=>e1); + -- a and b are equal if individual bits are equal + aeqb <= e0 and e1; +end struc_arch; \ No newline at end of file diff --git a/cores/curso/ch02/list_ch02_03_tb.vhd b/cores/curso/ch02/list_ch02_03_tb.vhd new file mode 100644 index 0000000..1cded3c --- /dev/null +++ b/cores/curso/ch02/list_ch02_03_tb.vhd @@ -0,0 +1,49 @@ +-- Listing 2.3 +library ieee; use ieee.std_logic_1164.all; +entity eq2_testbench is +end eq2_testbench; + +architecture tb_arch of eq2_testbench is + signal test_in0, test_in1: std_logic_vector(1 downto 0); + signal test_out: std_logic; +begin + -- instantiate the circuit under test + uut: entity work.eq2(struc_arch) + port map(a=>test_in0, b=>test_in1, aeqb=>test_out); + -- test vector generator + process + begin + -- test vector 1 + test_in0 <= "00"; + test_in1 <= "00"; + wait for 200 ns; + -- test vector 2 + test_in0 <= "01"; + test_in1 <= "00"; + wait for 200 ns; + -- test vector 3 + test_in0 <= "01"; + test_in1 <= "11"; + wait for 200 ns; + -- test vector 4 + test_in0 <= "10"; + test_in1 <= "10"; + wait for 200 ns; + -- test vector 5 + test_in0 <= "10"; + test_in1 <= "00"; + wait for 200 ns; + -- test vector 6 + test_in0 <= "11"; + test_in1 <= "11"; + wait for 200 ns; + -- test vector 7 + test_in0 <= "11"; + test_in1 <= "01"; + wait for 200 ns; + -- terminate simulation + assert false + report "Simulation Completed" + severity failure; + end process; +end tb_arch; \ No newline at end of file diff --git a/cores/curso/ch03/ch03_zxuno_v4.ucf b/cores/curso/ch03/ch03_zxuno_v4.ucf new file mode 100644 index 0000000..617c55b --- /dev/null +++ b/cores/curso/ch03/ch03_zxuno_v4.ucf @@ -0,0 +1,52 @@ +#======================================================== +# clock +#======================================================== +NET "clk" LOC="P55" | IOSTANDARD=LVCMOS33; + +#======================================================== +# buttons & switches +#======================================================== +# 5 push buttons +NET "bot<0>" LOC="P6" | IOSTANDARD=LVCMOS33 | PULLUP; #left +NET "bot<1>" LOC="P7" | IOSTANDARD=LVCMOS33 | PULLUP; #right +NET "bot<2>" LOC="P1" | IOSTANDARD=LVCMOS33 | PULLUP; #up +NET "bot<3>" LOC="P5" | IOSTANDARD=LVCMOS33 | PULLUP; #down +NET "bot<4>" LOC="P2" | IOSTANDARD=LVCMOS33 | PULLUP; #fire + +# 8 slide switches +NET "sw<0>" LOC="P51" | IOSTANDARD=LVCMOS33 | PULLUP; +NET "sw<1>" LOC="P46" | IOSTANDARD=LVCMOS33 | PULLUP; +NET "sw<2>" LOC="P45" | IOSTANDARD=LVCMOS33 | PULLUP; +NET "sw<3>" LOC="P50" | IOSTANDARD=LVCMOS33 | PULLUP; +NET "sw<4>" LOC="P48" | IOSTANDARD=LVCMOS33 | PULLUP; +NET "sw<5>" LOC="P57" | IOSTANDARD=LVCMOS33 | PULLUP; +NET "sw<6>" LOC="P56" | IOSTANDARD=LVCMOS33 | PULLUP; +NET "sw<7>" LOC="P58" | IOSTANDARD=LVCMOS33 | PULLUP; + +#======================================================== +# 4-digit time-multiplexed 7-segment LED display +#======================================================== +# digit enable +NET "an<0>" LOC="P30" | IOSTANDARD=LVCMOS33; +NET "an<1>" LOC="P29" | IOSTANDARD=LVCMOS33; +NET "an<2>" LOC="P15" | IOSTANDARD=LVCMOS33; +NET "an<3>" LOC="P32" | IOSTANDARD=LVCMOS33; + +# 7-segment led segments +NET "sseg<7>" LOC="P23" | IOSTANDARD=LVCMOS33; # decimal point +NET "sseg<6>" LOC="P16" | IOSTANDARD=LVCMOS33; # segment a +NET "sseg<5>" LOC="P22" | IOSTANDARD=LVCMOS33; # segment b +NET "sseg<4>" LOC="P24" | IOSTANDARD=LVCMOS33; # segment c +NET "sseg<3>" LOC="P12" | IOSTANDARD=LVCMOS33; # segment d +NET "sseg<2>" LOC="P21" | IOSTANDARD=LVCMOS33; # segment e +NET "sseg<1>" LOC="P26" | IOSTANDARD=LVCMOS33; # segment f +NET "sseg<0>" LOC="P27" | IOSTANDARD=LVCMOS33; # segment g + +#======================================================== +# 5 discrete led +#======================================================== +NET "led<0>" LOC="P34" | IOSTANDARD=LVCMOS33; +NET "led<1>" LOC="P35" | IOSTANDARD=LVCMOS33; +NET "led<2>" LOC="P41" | IOSTANDARD=LVCMOS33; +NET "led<3>" LOC="P43" | IOSTANDARD=LVCMOS33; +NET "led<4>" LOC="P47" | IOSTANDARD=LVCMOS33; diff --git a/cores/curso/ch03/disp_mux.vhd b/cores/curso/ch03/disp_mux.vhd new file mode 100644 index 0000000..5877731 --- /dev/null +++ b/cores/curso/ch03/disp_mux.vhd @@ -0,0 +1,55 @@ +-- Listing 4.13 +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +entity disp_mux is + port( + clk, reset: in std_logic; + in3, in2, in1, in0: in std_logic_vector(6 downto 0); + point: in std_logic; + colon: in std_logic; + an: out std_logic_vector(3 downto 0); + sseg: out std_logic_vector(7 downto 0) + ); +end disp_mux ; + +architecture arch of disp_mux is + -- refreshing rate around 800 Hz (50MHz/2^16) + constant N: integer:=18; + signal q_reg, q_next: unsigned(N-1 downto 0); + signal sel: std_logic_vector(1 downto 0); +begin + -- register + process(clk,reset) + begin + if reset='1' then + q_reg <= (others=>'0'); + elsif (clk'event and clk='1') then + q_reg <= q_next; + end if; + end process; + + -- next-state logic for the counter + q_next <= q_reg + 1; + + -- 2 MSBs of counter to control 4-to-1 multiplexing + -- and to generate active-low enable signal + sel <= std_logic_vector(q_reg(N-1 downto N-2)); + process(sel,in0,in1,in2,in3,colon,point) + begin + case sel is + when "00" => + an <= "1110"; + sseg <= '1' & in0; + when "01" => + an <= "1101"; + sseg <= '1' & in1; + when "10" => + an <= "1011"; + sseg <= colon & in2; + when others => + an <= "0111"; + sseg <= point & in3; + end case; + end process; +end arch; diff --git a/cores/curso/ch03/hex_to_sseg.vhd b/cores/curso/ch03/hex_to_sseg.vhd new file mode 100644 index 0000000..7f57d29 --- /dev/null +++ b/cores/curso/ch03/hex_to_sseg.vhd @@ -0,0 +1,31 @@ +-- Listing 3.12 +library ieee; +use ieee.std_logic_1164.all; +entity hex_to_sseg is + port( + hex: in std_logic_vector(3 downto 0); + sseg: out std_logic_vector(6 downto 0) + ); +end hex_to_sseg; + +architecture arch of hex_to_sseg is +begin + with hex select + sseg <= + "0000001" when "0000", + "1001111" when "0001", + "0010010" when "0010", + "0000110" when "0011", + "1001100" when "0100", + "0100100" when "0101", + "0100000" when "0110", + "0001111" when "0111", + "0000000" when "1000", + "0000100" when "1001", + "0001000" when "1010", --a + "1100000" when "1011", --b + "0110001" when "1100", --c + "1000010" when "1101", --d + "0110000" when "1110", --e + "0111000" when others; --f +end arch; diff --git a/cores/curso/ch03/hex_to_sseg_test.prj b/cores/curso/ch03/hex_to_sseg_test.prj new file mode 100644 index 0000000..4a23f1f --- /dev/null +++ b/cores/curso/ch03/hex_to_sseg_test.prj @@ -0,0 +1,3 @@ +vhdl work "list_ch03_13_led_test.vhd" +vhdl work "hex_to_sseg.vhd" +vhdl work "disp_mux.vhd" diff --git a/cores/curso/cap1/main.ut b/cores/curso/ch03/hex_to_sseg_test.ut similarity index 100% rename from cores/curso/cap1/main.ut rename to cores/curso/ch03/hex_to_sseg_test.ut diff --git a/cores/curso/ch03/hex_to_sseg_test.xst b/cores/curso/ch03/hex_to_sseg_test.xst new file mode 100644 index 0000000..9fa1e49 --- /dev/null +++ b/cores/curso/ch03/hex_to_sseg_test.xst @@ -0,0 +1,53 @@ +set -tmpdir "projnav.tmp" +set -xsthdpdir "xst" +run +-ifn hex_to_sseg_test.prj +-infer_ramb8 No -loop_iteration_limit 32768 +-ofn hex_to_sseg_test +-ofmt NGC +-p xc6slx9-2-tqg144 +-top hex_to_sseg_test +-opt_mode Speed +-opt_level 2 +-power NO +-uc "timings.xcf" +-iuc NO +-keep_hierarchy No +-netlist_hierarchy As_Optimized +-rtlview Yes +-glob_opt AllClockNets +-read_cores YES +-write_timing_constraints YES +-cross_clock_analysis NO +-hierarchy_separator / +-bus_delimiter <> +-case Maintain +-slice_utilization_ratio 100 +-bram_utilization_ratio 100 +-dsp_utilization_ratio 100 +-lc Auto +-reduce_control_sets Auto +-fsm_extract NO +-fsm_style LUT +-ram_extract Yes +-ram_style Auto +-rom_extract Yes +-shreg_extract YES +-rom_style Auto +-auto_bram_packing NO +-resource_sharing YES +-async_to_sync YES +-shreg_min_size 2 +-use_dsp48 Auto +-iobuf YES +-max_fanout 100000 +-bufg 16 +-register_duplication YES +-register_balancing No +-optimize_primitives NO +-use_clock_enable Auto +-use_sync_set Auto +-use_sync_reset Auto +-iob Auto +-equivalent_register_removal YES +-slice_utilization_ratio_maxmargin 5 diff --git a/cores/curso/ch03/list_ch03_01_03_05_07_prio.vhd b/cores/curso/ch03/list_ch03_01_03_05_07_prio.vhd new file mode 100644 index 0000000..517547d --- /dev/null +++ b/cores/curso/ch03/list_ch03_01_03_05_07_prio.vhd @@ -0,0 +1,71 @@ +--Listing 3.1 +library ieee; +use ieee.std_logic_1164.all; +entity prio_encoder is + port( + r: in std_logic_vector(4 downto 1); + pcode: out std_logic_vector(2 downto 0) + ); +end prio_encoder; + +architecture cond_arch of prio_encoder is +begin + pcode <= "100" when (r(4)='1') else + "011" when (r(3)='1') else + "010" when (r(2)='1') else + "001" when (r(1)='1') else + "000"; +end cond_arch; + + +--Listing 3.3 +architecture sel_arch of prio_encoder is +begin + with r select + pcode <= "100" when "1000"|"1001"|"1010"|"1011"| + "1100"|"1101"|"1110"|"1111", + "011" when "0100"|"0101"|"0110"|"0111", + "010" when "0010"|"0011", + "001" when "0001", + "000" when others; -- r="0000" +end sel_arch; + +--Listing 3.5 +architecture if_arch of prio_encoder is +begin + process(r) + begin + if (r(4)='1') then + pcode <= "100"; + elsif (r(3)='1')then + pcode <= "011"; + elsif (r(2)='1')then + pcode <= "010"; + elsif (r(1)='1')then + pcode <= "001"; + else + pcode <= "000"; + end if; + end process; +end if_arch; + +--Listing 3.7 +architecture case_arch of prio_encoder is +begin + process(r) + begin + case r is + when "1000"|"1001"|"1010"|"1011"| + "1100"|"1101"|"1110"|"1111" => + pcode <= "100"; + when "0100"|"0101"|"0110"|"0111" => + pcode <= "011"; + when "0010"|"0011" => + pcode <= "010"; + when "0001" => + pcode <= "001"; + when others => + pcode <= "000"; + end case; + end process; +end case_arch; \ No newline at end of file diff --git a/cores/curso/ch03/list_ch03_02_04_06_08_decode.vhd b/cores/curso/ch03/list_ch03_02_04_06_08_decode.vhd new file mode 100644 index 0000000..3266680 --- /dev/null +++ b/cores/curso/ch03/list_ch03_02_04_06_08_decode.vhd @@ -0,0 +1,73 @@ +--Listing 3.2 +library ieee; +use ieee.std_logic_1164.all; +entity decoder_2_4 is + port( + a: in std_logic_vector(1 downto 0); + en: in std_logic; + y: out std_logic_vector(3 downto 0) + ); +end decoder_2_4; + +architecture cond_arch of decoder_2_4 is +begin + y <= "0000" when (en='0') else + "0001" when (a="00") else + "0010" when (a="01") else + "0100" when (a="10") else + "1000"; -- a="11" +end cond_arch; + + +--Listing 3.4 +architecture sel_arch of decoder_2_4 is + signal s: std_logic_vector(2 downto 0); +begin + s <= en & a; + with s select + y <= "0000" when "000"|"001"|"010"|"011", + "0001" when "100", + "0010" when "101", + "0100" when "110", + "1000" when others; -- s="111" +end sel_arch; + +--Listing 3.6 +architecture if_arch of decoder_2_4 is begin + process(en,a) + begin + if (en='0') then + y <= "0000"; + elsif (a="00") then + y <= "0001"; + elsif (a="01")then + y <= "0010"; + elsif (a="10")then + y <= "0100"; + else + y <= "1000"; + end if; + end process; +end if_arch; + +--Listing 3.8 +architecture case_arch of decoder_2_4 is + signal s: std_logic_vector(2 downto 0); +begin + s <= en & a; + process(s) + begin + case s is + when "000"|"001"|"010"|"011" => + y <= "0001"; + when "100" => + y <= "0001"; + when "101" => + y <= "0010"; + when "110" => + y <= "0100"; + when others => + y <= "1000"; + end case; + end process; +end case_arch; \ No newline at end of file diff --git a/cores/curso/ch03/list_ch03_09_10_add.vhd b/cores/curso/ch03/list_ch03_09_10_add.vhd new file mode 100644 index 0000000..43a0cf4 --- /dev/null +++ b/cores/curso/ch03/list_ch03_09_10_add.vhd @@ -0,0 +1,33 @@ +-- Listing 3.9 +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +entity add_w_carry is + port( + a, b: in std_logic_vector(3 downto 0); + cout: out std_logic; + sum: out std_logic_vector(3 downto 0) + ); +end add_w_carry; + +architecture hard_arch of add_w_carry is + signal a_ext, b_ext, sum_ext: unsigned(4 downto 0); +begin + a_ext <= unsigned('0' & a); + b_ext <= unsigned('0' & b); + sum_ext <= a_ext + b_ext; + sum <= std_logic_vector(sum_ext(3 downto 0)); + cout <= sum_ext(4); +end hard_arch; + +-- Listing 3.10 +architecture const_arch of add_w_carry is + constant N: integer := 4; + signal a_ext, b_ext, sum_ext: unsigned(N downto 0); +begin + a_ext <= unsigned('0' & a); + b_ext <= unsigned('0' & b); + sum_ext <= a_ext + b_ext; + sum <= std_logic_vector(sum_ext(N-1 downto 0)); + cout <= sum_ext(N); +end const_arch; \ No newline at end of file diff --git a/cores/curso/ch03/list_ch03_11_gen_add.vhd b/cores/curso/ch03/list_ch03_11_gen_add.vhd new file mode 100644 index 0000000..19a5011 --- /dev/null +++ b/cores/curso/ch03/list_ch03_11_gen_add.vhd @@ -0,0 +1,22 @@ +--Listing 3.11 +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +entity gen_add_w_carry is + generic(N: integer:=4); + port( + a, b: in std_logic_vector(N-1 downto 0); + cout: out std_logic; + sum: out std_logic_vector(N-1 downto 0) + ); +end gen_add_w_carry; + +architecture arch of gen_add_w_carry is + signal a_ext, b_ext, sum_ext: unsigned(N downto 0); +begin + a_ext <= unsigned('0' & a); + b_ext <= unsigned('0' & b); + sum_ext <= a_ext + b_ext; + sum <= std_logic_vector(sum_ext(N-1 downto 0)); + cout <= sum_ext(N); +end arch; \ No newline at end of file diff --git a/cores/curso/ch03/list_ch03_12_hex2led.vhd b/cores/curso/ch03/list_ch03_12_hex2led.vhd new file mode 100644 index 0000000..bf0dfbc --- /dev/null +++ b/cores/curso/ch03/list_ch03_12_hex2led.vhd @@ -0,0 +1,33 @@ +-- Listing 3.12 +library ieee; +use ieee.std_logic_1164.all; +entity hex_to_sseg is + port( + hex: in std_logic_vector(3 downto 0); + dp: in std_logic; + sseg: out std_logic_vector(7 downto 0) + ); +end hex_to_sseg; + +architecture arch of hex_to_sseg is +begin + with hex select + sseg(6 downto 0) <= + "0000001" when "0000", + "1001111" when "0001", + "0010010" when "0010", + "0000110" when "0011", + "1001100" when "0100", + "0100100" when "0101", + "0100000" when "0110", + "0001111" when "0111", + "0000000" when "1000", + "0000100" when "1001", + "0001000" when "1010", --a + "1100000" when "1011", --b + "0110001" when "1100", --c + "1000010" when "1101", --d + "0110000" when "1110", --e + "0111000" when others; --f + sseg(7) <= dp; +end arch; \ No newline at end of file diff --git a/cores/curso/ch03/list_ch03_13_led_test.vhd b/cores/curso/ch03/list_ch03_13_led_test.vhd new file mode 100644 index 0000000..5a8284a --- /dev/null +++ b/cores/curso/ch03/list_ch03_13_led_test.vhd @@ -0,0 +1,47 @@ +-- Listing 3.13 +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +entity hex_to_sseg_test is + port( + clk: in std_logic; + bot: in std_logic_vector(4 downto 0); + sw: in std_logic_vector(7 downto 0); + led: out std_logic_vector(4 downto 0); + an: out std_logic_vector(3 downto 0); + sseg: out std_logic_vector(7 downto 0) + ); +end hex_to_sseg_test; + +architecture arch of hex_to_sseg_test is + signal inc: std_logic_vector(7 downto 0); + signal led3, led2, led1, led0: std_logic_vector(6 downto 0); +begin + + led <= not bot; + + -- increment input + inc <= std_logic_vector(unsigned(sw) + 1); + + -- instantiate four instances of hex decoders + -- instance for 4 LSBs of input + sseg_unit_0: entity work.hex_to_sseg + port map(hex=>sw(3 downto 0), sseg=>led0); + -- instance for 4 MSBs of input + sseg_unit_1: entity work.hex_to_sseg + port map(hex=>sw(7 downto 4), sseg=>led1); + -- instance for 4 LSBs of incremented value + sseg_unit_2: entity work.hex_to_sseg + port map(hex=>inc(3 downto 0), sseg=>led2); + -- instance for 4 MSBs of incremented value + sseg_unit_3: entity work.hex_to_sseg + port map(hex=>inc(7 downto 4), sseg=>led3); + + -- instantiate 7-seg LED display time-multiplexing module + disp_unit: entity work.disp_mux + port map( + clk=>clk, reset=>'0', + in0=>led0, in1=>led1, in2=>led2, in3=>led3, + point=>'1', colon=>'0', + an=>an, sseg=>sseg); +end arch; diff --git a/cores/curso/ch03/list_ch03_14_smadd.vhd b/cores/curso/ch03/list_ch03_14_smadd.vhd new file mode 100644 index 0000000..62aed10 --- /dev/null +++ b/cores/curso/ch03/list_ch03_14_smadd.vhd @@ -0,0 +1,40 @@ +-- Listing 3.14 +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +entity sign_mag_add is + generic(N: integer:=4); -- default 4 bits + port( + a, b: in std_logic_vector(N-1 downto 0); + sum: out std_logic_vector(N-1 downto 0) + ); +end sign_mag_add; + +architecture arch of sign_mag_add is + signal mag_a, mag_b: unsigned(N-2 downto 0); + signal mag_sum, max, min: unsigned(N-2 downto 0); + signal sign_a, sign_b, sign_sum: std_logic; +begin + mag_a <= unsigned(a(N-2 downto 0)); + mag_b <= unsigned(b(N-2 downto 0)); + sign_a <= a(N-1); + sign_b <= b(N-1); + -- sort according to magnitude + process(mag_a,mag_b,sign_a,sign_b) + begin + if mag_a > mag_b then + max <= mag_a; + min <= mag_b; + sign_sum <= sign_a; + else + max <= mag_b; + min <= mag_a; + sign_sum <= sign_b; + end if; + end process; + -- add/sub magnitude + mag_sum <= max + min when sign_a=sign_b else + max - min; + --form output + sum <= std_logic_vector(sign_sum & mag_sum); +end arch; diff --git a/cores/curso/ch03/list_ch03_15_smadd_test.vhd b/cores/curso/ch03/list_ch03_15_smadd_test.vhd new file mode 100644 index 0000000..b846759 --- /dev/null +++ b/cores/curso/ch03/list_ch03_15_smadd_test.vhd @@ -0,0 +1,55 @@ +-- Listing 3.15 +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +entity sm_add_test is + port( + clk: in std_logic; + bot: in std_logic_vector(4 downto 0); + sw: in std_logic_vector(7 downto 0); + led: out std_logic_vector(4 downto 0); + an: out std_logic_vector(3 downto 0); + sseg: out std_logic_vector(7 downto 0) + ); +end sm_add_test; + +architecture arch of sm_add_test is + signal sum, mout, oct: std_logic_vector(3 downto 0); + signal btn : std_logic_vector(1 downto 0); + signal led3, led2, led1, led0: std_logic_vector(6 downto 0); +begin + + btn <= not bot(1 downto 0); + led <= not bot; + + -- instantiate adder + sm_adder_unit: entity work.sign_mag_add + generic map(N=>4) + port map(a=>sw(3 downto 0), b=>sw(7 downto 4), + sum=>sum); + + -- 3-to-1 mux to select a number to display + with btn select + mout <= sw(3 downto 0) when "00", -- a + sw(7 downto 4) when "01", -- b + sum when others; -- sum + + -- magnitude displayed on rightmost 7-seg LED + oct <= '0' & mout(2 downto 0); + sseg_unit: entity work.hex_to_sseg + port map(hex=>oct, sseg=>led0); + -- sign displayed on 2nd 7-seg LED + led1 <= "1111110" when mout(3)='1' else -- middle bar + "1111111"; -- blank + -- other two 7-seg LEDs blank + led2 <= "1111111"; + led3 <= "1111111"; + + -- instantiate display multiplexer + disp_unit: entity work.disp_mux + port map( + clk=>clk, reset=>'0', + in0=>led0, in1=>led1, in2=>led2, in3=>led3, + point=>'1', colon=>'1', + an=>an, sseg=>sseg); +end arch; diff --git a/cores/curso/ch03/make.bat b/cores/curso/ch03/make.bat new file mode 100644 index 0000000..a9e19c1 --- /dev/null +++ b/cores/curso/ch03/make.bat @@ -0,0 +1,10 @@ +SET machine=hex_to_sseg_test +SET speed=2 +SET ruta_ucf=ch03 +SET ruta_bat=..\..\ +rem call %ruta_bat%genxst.bat +rem call %ruta_bat%generar.bat v4 + +SET machine=sm_add_test +call %ruta_bat%genxst.bat +call %ruta_bat%generar.bat v4 diff --git a/cores/curso/ch03/sm_add_test.prj b/cores/curso/ch03/sm_add_test.prj new file mode 100644 index 0000000..1881857 --- /dev/null +++ b/cores/curso/ch03/sm_add_test.prj @@ -0,0 +1,4 @@ +vhdl work "list_ch03_15_smadd_test.vhd" +vhdl work "list_ch03_14_smadd.vhd" +vhdl work "hex_to_sseg.vhd" +vhdl work "disp_mux.vhd" diff --git a/cores/curso/ch03/sm_add_test.ut b/cores/curso/ch03/sm_add_test.ut new file mode 100644 index 0000000..e72e557 --- /dev/null +++ b/cores/curso/ch03/sm_add_test.ut @@ -0,0 +1,31 @@ +-w +-g Binary:no +-g Compress +-g CRC:Enable +-g Reset_on_err:No +-g ConfigRate:2 +-g ProgPin:PullUp +-g TckPin:PullUp +-g TdiPin:PullUp +-g TdoPin:PullUp +-g TmsPin:PullUp +-g UnusedPin:PullDown +-g UserID:0xFFFFFFFF +-g ExtMasterCclk_en:Yes +-g ExtMasterCclk_divide:50 +-g SPI_buswidth:1 +-g TIMER_CFG:0xFFFF +-g multipin_wakeup:No +-g StartUpClk:CClk +-g DONE_cycle:4 +-g GTS_cycle:5 +-g GWE_cycle:6 +-g LCK_cycle:NoWait +-g Security:None +-g DonePipe:No +-g DriveDone:No +-g en_sw_gsr:No +-g drive_awake:No +-g sw_clk:Startupclk +-g sw_gwe_cycle:5 +-g sw_gts_cycle:4 diff --git a/cores/curso/cap1/main.xst b/cores/curso/ch03/sm_add_test.xst similarity index 94% rename from cores/curso/cap1/main.xst rename to cores/curso/ch03/sm_add_test.xst index e3b6dc3..a473ff2 100644 --- a/cores/curso/cap1/main.xst +++ b/cores/curso/ch03/sm_add_test.xst @@ -1,12 +1,12 @@ set -tmpdir "projnav.tmp" set -xsthdpdir "xst" run --ifn main.prj +-ifn sm_add_test.prj -infer_ramb8 No -loop_iteration_limit 32768 --ofn main +-ofn sm_add_test -ofmt NGC -p xc6slx9-2-tqg144 --top main +-top sm_add_test -opt_mode Speed -opt_level 2 -power NO diff --git a/cores/curso/ch03/timings.xcf b/cores/curso/ch03/timings.xcf new file mode 100644 index 0000000..7ce464f --- /dev/null +++ b/cores/curso/ch03/timings.xcf @@ -0,0 +1,2 @@ +# Timing constraints +NET "clk" PERIOD=20 ns;