diff --git a/cores/curso/ch04/fifo_test.prj b/cores/curso/ch04/fifo_test.prj new file mode 100644 index 0000000..4255fac --- /dev/null +++ b/cores/curso/ch04/fifo_test.prj @@ -0,0 +1,2 @@ +vhdl work "list_ch04_21_fifo_test.vhd" +vhdl work "list_ch04_20_fifo.vhd" diff --git a/cores/curso/ch04/fifo_test.ut b/cores/curso/ch04/fifo_test.ut new file mode 100644 index 0000000..a9facca --- /dev/null +++ b/cores/curso/ch04/fifo_test.ut @@ -0,0 +1,30 @@ +-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:No +-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/ch04/fifo_test.xst b/cores/curso/ch04/fifo_test.xst new file mode 100644 index 0000000..5535fd4 --- /dev/null +++ b/cores/curso/ch04/fifo_test.xst @@ -0,0 +1,53 @@ +set -tmpdir "projnav.tmp" +set -xsthdpdir "xst" +run +-ifn fifo_test.prj +-infer_ramb8 No -loop_iteration_limit 32768 +-ofn fifo_test +-ofmt NGC +-p xc6slx9-2-tqg144 +-top fifo_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/ch04/list_ch04_17_18_watch.vhd b/cores/curso/ch04/list_ch04_17_18_watch.vhd new file mode 100644 index 0000000..1185d2b --- /dev/null +++ b/cores/curso/ch04/list_ch04_17_18_watch.vhd @@ -0,0 +1,134 @@ +--=================================== +-- Listing 4.17 +--=================================== +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +entity stop_watch is + port( + clk: in std_logic; + go, clr: in std_logic; + d2, d1, d0: out std_logic_vector(3 downto 0) + ); +end stop_watch; + +architecture cascade_arch of stop_watch is + constant DVSR: integer:=5000000; + signal ms_reg, ms_next: unsigned(22 downto 0); + signal d2_reg, d1_reg, d0_reg: unsigned(3 downto 0); + signal d2_next, d1_next, d0_next: unsigned(3 downto 0); + signal d1_en, d2_en, d0_en: std_logic; + signal ms_tick, d0_tick, d1_tick: std_logic; +begin + -- register + process(clk) + begin + if (clk'event and clk='1') then + ms_reg <= ms_next; + d2_reg <= d2_next; + d1_reg <= d1_next; + d0_reg <= d0_next; + end if; + end process; + + -- next-state logic + -- 0.1 sec tick generator: mod-5000000 + ms_next <= + (others=>'0') when clr='1' or + (ms_reg=DVSR and go='1') else + ms_reg + 1 when go='1' else + ms_reg; + ms_tick <= '1' when ms_reg=DVSR else '0'; + -- 0.1 sec counter + d0_en <= '1' when ms_tick='1' else '0'; + d0_next <= + "0000" when (clr='1') or (d0_en='1' and d0_reg=9) else + d0_reg + 1 when d0_en='1' else + d0_reg; + d0_tick <= '1' when d0_reg=9 else '0'; + -- 1 sec counter + d1_en <= '1' when ms_tick='1' and d0_tick='1' else '0'; + d1_next <= + "0000" when (clr='1') or (d1_en='1' and d1_reg=9) else + d1_reg + 1 when d1_en='1' else + d1_reg; + d1_tick <= '1' when d1_reg=9 else '0'; + -- 10 sec counter + d2_en <= + '1' when ms_tick='1' and d0_tick='1' and d1_tick='1' else + '0'; + d2_next <= + "0000" when (clr='1') or (d2_en='1' and d2_reg=9) else + d2_reg + 1 when d2_en='1' else + d2_reg; + + -- output logic + d0 <= std_logic_vector(d0_reg); + d1 <= std_logic_vector(d1_reg); + d2 <= std_logic_vector(d2_reg); +end cascade_arch; + + +--=================================== +-- Listing 4.18 +--=================================== +architecture if_arch of stop_watch is + constant DVSR: integer:=5000000; + signal ms_reg, ms_next: unsigned(22 downto 0); + signal d2_reg, d1_reg, d0_reg: unsigned(3 downto 0); + signal d2_next, d1_next, d0_next: unsigned(3 downto 0); + signal ms_tick: std_logic; +begin + -- register + process(clk) + begin + if (clk'event and clk='1') then + ms_reg <= ms_next; + d2_reg <= d2_next; + d1_reg <= d1_next; + d0_reg <= d0_next; + end if; + end process; + + -- next-state logic + -- 0.1 sec tick generator: mod-5000000 + ms_next <= + (others=>'0') when clr='1' or + (ms_reg=DVSR and go='1') else + ms_reg + 1 when go='1' else + ms_reg; + ms_tick <= '1' when ms_reg=DVSR else '0'; + -- 0.1 sec counter + process(d0_reg,d1_reg,d2_reg,ms_tick,clr) + begin + -- defult + d0_next <= d0_reg; + d1_next <= d1_reg; + d2_next <= d2_reg; + if clr='1' then + d0_next <= "0000"; + d1_next <= "0000"; + d2_next <= "0000"; + elsif ms_tick='1' then + if (d0_reg/=9) then + d0_next <= d0_reg + 1; + else -- reach XX9 + d0_next <= "0000"; + if (d1_reg/=9) then + d1_next <= d1_reg + 1; + else -- reach X99 + d1_next <= "0000"; + if (d2_reg/=9) then + d2_next <= d2_reg + 1; + else -- reach 999 + d2_next <= "0000"; + end if; + end if; + end if; + end if; + end process; + -- output logic + d0 <= std_logic_vector(d0_reg); + d1 <= std_logic_vector(d1_reg); + d2 <= std_logic_vector(d2_reg); +end if_arch; diff --git a/cores/curso/ch04/list_ch04_19_watch_test.vhd b/cores/curso/ch04/list_ch04_19_watch_test.vhd new file mode 100644 index 0000000..6d93c7e --- /dev/null +++ b/cores/curso/ch04/list_ch04_19_watch_test.vhd @@ -0,0 +1,34 @@ +--Listing 4.19 +library ieee; +use ieee.std_logic_1164.all; +entity stop_watch_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 stop_watch_test; + +architecture arch of stop_watch_test is + signal d2, d1, d0: std_logic_vector(3 downto 0); + signal btn: std_logic_vector(1 downto 0); +begin + + led <= not bot; + btn <= not bot(1 downto 0); + + disp_unit: entity work.disp_hex_mux + port map( + clk=>clk, reset=>'0', + hex3=>"0000", hex2=>d2, hex1=>d1, hex0=>d0, + point=>'1', colon=>'0', + an=>an, sseg=>sseg); + + watch_unit: entity work.stop_watch(cascade_arch) + port map( + clk=>clk, go=>btn(1), clr=>btn(0), + d2 =>d2, d1=>d1, d0=>d0 ); +end arch; diff --git a/cores/curso/ch04/list_ch04_20_fifo.vhd b/cores/curso/ch04/list_ch04_20_fifo.vhd new file mode 100644 index 0000000..a347910 --- /dev/null +++ b/cores/curso/ch04/list_ch04_20_fifo.vhd @@ -0,0 +1,109 @@ +-- Listing 4.20 +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +entity fifo is + generic( + B: natural:=8; -- number of bits + W: natural:=4 -- number of address bits + ); + port( + clk, reset: in std_logic; + rd, wr: in std_logic; + w_data: in std_logic_vector (B-1 downto 0); + empty, full: out std_logic; + r_data: out std_logic_vector (B-1 downto 0) + ); +end fifo; + +architecture arch of fifo is + type reg_file_type is array (2**W-1 downto 0) of + std_logic_vector(B-1 downto 0); + signal array_reg: reg_file_type; + signal w_ptr_reg, w_ptr_next, w_ptr_succ: + std_logic_vector(W-1 downto 0); + signal r_ptr_reg, r_ptr_next, r_ptr_succ: + std_logic_vector(W-1 downto 0); + signal full_reg, empty_reg, full_next, empty_next: + std_logic; + signal wr_op: std_logic_vector(1 downto 0); + signal wr_en: std_logic; +begin + --================================================= + -- register file + --================================================= + process(clk,reset) + begin + if (reset='1') then + array_reg <= (others=>(others=>'0')); + elsif (clk'event and clk='1') then + if wr_en='1' then + array_reg(to_integer(unsigned(w_ptr_reg))) + <= w_data; + end if; + end if; + end process; + -- read port + r_data <= array_reg(to_integer(unsigned(r_ptr_reg))); + -- write enabled only when FIFO is not full + wr_en <= wr and (not full_reg); + + --================================================= + -- fifo control logic + --================================================= + -- register for read and write pointers + process(clk,reset) + begin + if (reset='1') then + w_ptr_reg <= (others=>'0'); + r_ptr_reg <= (others=>'0'); + full_reg <= '0'; + empty_reg <= '1'; + elsif (clk'event and clk='1') then + w_ptr_reg <= w_ptr_next; + r_ptr_reg <= r_ptr_next; + full_reg <= full_next; + empty_reg <= empty_next; + end if; + end process; + + -- successive pointer values + w_ptr_succ <= std_logic_vector(unsigned(w_ptr_reg)+1); + r_ptr_succ <= std_logic_vector(unsigned(r_ptr_reg)+1); + + -- next-state logic for read and write pointers + wr_op <= wr & rd; + process(w_ptr_reg,w_ptr_succ,r_ptr_reg,r_ptr_succ,wr_op, + empty_reg,full_reg) + begin + w_ptr_next <= w_ptr_reg; + r_ptr_next <= r_ptr_reg; + full_next <= full_reg; + empty_next <= empty_reg; + case wr_op is + when "00" => -- no op + when "01" => -- read + if (empty_reg /= '1') then -- not empty + r_ptr_next <= r_ptr_succ; + full_next <= '0'; + if (r_ptr_succ=w_ptr_reg) then + empty_next <='1'; + end if; + end if; + when "10" => -- write + if (full_reg /= '1') then -- not full + w_ptr_next <= w_ptr_succ; + empty_next <= '0'; + if (w_ptr_succ=r_ptr_reg) then + full_next <='1'; + end if; + end if; + when others => -- write/read; + w_ptr_next <= w_ptr_succ; + r_ptr_next <= r_ptr_succ; + end case; + end process; + -- output + full <= full_reg; + empty <= empty_reg; +end arch; diff --git a/cores/curso/ch04/list_ch04_21_fifo_test.vhd b/cores/curso/ch04/list_ch04_21_fifo_test.vhd new file mode 100644 index 0000000..e778a63 --- /dev/null +++ b/cores/curso/ch04/list_ch04_21_fifo_test.vhd @@ -0,0 +1,36 @@ +-- Listing 4.21 +library ieee; +use ieee.std_logic_1164.all; +entity fifo_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 fifo_test; + +architecture arch of fifo_test is + signal btn, db_btn: std_logic_vector(2 downto 0); +begin + + sseg <= "11111111"; + an <= "1111"; + btn <= not bot(2 downto 0); + + -- debounce circuit for btn(0) + btn_db_unit0: entity work.debounce(fsmd_arch) + port map(clk=>clk, reset=>btn(2), sw=>btn(0), db=>db_btn(0)); + -- debounce circuit for btn(1) + btn_db_unit1: entity work.debounce(fsmd_arch) + port map(clk=>clk, reset=>btn(2), sw=>btn(1), db=>db_btn(1)); + -- instantiate a 2^2-by-3 fifo) + fifo_unit: entity work.fifo(arch) + generic map(B=>3, W=>2) + port map(clk=>clk, reset=>btn(2), + rd=>db_btn(0), wr=>db_btn(1), + w_data=>sw(2 downto 0), r_data=>led(2 downto 0), + full=>led(4), empty=>led(3)); +end arch; diff --git a/cores/curso/ch04/make.bat b/cores/curso/ch04/make.bat index 6e3e2c4..1819d3c 100644 --- a/cores/curso/ch04/make.bat +++ b/cores/curso/ch04/make.bat @@ -1,10 +1,10 @@ SET speed=2 SET ruta_ucf=ch04 SET ruta_bat=..\..\ -rem call :genbitstream disp_mux_test +call :genbitstream disp_mux_test call :genbitstream hex_mux_test -rem call :genbitstream shifter_test -rem call :genbitstream fp_adder_test +call :genbitstream stop_watch_test +call :genbitstream fifo_test goto :eof :genbitstream diff --git a/cores/curso/ch04/stop_watch_test.prj b/cores/curso/ch04/stop_watch_test.prj new file mode 100644 index 0000000..dd31860 --- /dev/null +++ b/cores/curso/ch04/stop_watch_test.prj @@ -0,0 +1,2 @@ +vhdl work "list_ch04_19_watch_test.vhd" +vhdl work "list_ch04_17_18_watch.vhd" diff --git a/cores/curso/ch04/stop_watch_test.ut b/cores/curso/ch04/stop_watch_test.ut new file mode 100644 index 0000000..a9facca --- /dev/null +++ b/cores/curso/ch04/stop_watch_test.ut @@ -0,0 +1,30 @@ +-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:No +-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/ch04/stop_watch_test.xst b/cores/curso/ch04/stop_watch_test.xst new file mode 100644 index 0000000..f4c6f95 --- /dev/null +++ b/cores/curso/ch04/stop_watch_test.xst @@ -0,0 +1,53 @@ +set -tmpdir "projnav.tmp" +set -xsthdpdir "xst" +run +-ifn stop_watch_test.prj +-infer_ramb8 No -loop_iteration_limit 32768 +-ofn stop_watch_test +-ofmt NGC +-p xc6slx9-2-tqg144 +-top stop_watch_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