From 91cd8413e39df53d6fa6094bc0fc9725e64946c7 Mon Sep 17 00:00:00 2001 From: antoniovillena Date: Sun, 11 Dec 2016 21:20:18 +0100 Subject: [PATCH] =?UTF-8?q?A=C3=B1ado=20ch07?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cores/curso/ch06/debounce_test.prj | 1 + cores/curso/ch06/list_ch06_03_db_test.vhd | 10 +- cores/curso/ch07/ch07_zxuno_v4.ucf | 44 +++++++++ cores/curso/ch07/list_ch07_01_uart_rx.vhd | 91 +++++++++++++++++ cores/curso/ch07/list_ch07_02_flag.vhd | 45 +++++++++ cores/curso/ch07/list_ch07_03_uart_tx.vhd | 102 ++++++++++++++++++++ cores/curso/ch07/list_ch07_04_uart.vhd | 63 ++++++++++++ cores/curso/ch07/list_ch07_05_uart_test.vhd | 42 ++++++++ cores/curso/ch07/make.bat | 12 +++ cores/curso/ch07/timings.xcf | 2 + cores/curso/ch07/uart_test.prj | 6 ++ cores/curso/ch07/uart_test.ut | 30 ++++++ cores/curso/ch07/uart_test.xst | 53 ++++++++++ 13 files changed, 499 insertions(+), 2 deletions(-) create mode 100644 cores/curso/ch07/ch07_zxuno_v4.ucf create mode 100644 cores/curso/ch07/list_ch07_01_uart_rx.vhd create mode 100644 cores/curso/ch07/list_ch07_02_flag.vhd create mode 100644 cores/curso/ch07/list_ch07_03_uart_tx.vhd create mode 100644 cores/curso/ch07/list_ch07_04_uart.vhd create mode 100644 cores/curso/ch07/list_ch07_05_uart_test.vhd create mode 100644 cores/curso/ch07/make.bat create mode 100644 cores/curso/ch07/timings.xcf create mode 100644 cores/curso/ch07/uart_test.prj create mode 100644 cores/curso/ch07/uart_test.ut create mode 100644 cores/curso/ch07/uart_test.xst diff --git a/cores/curso/ch06/debounce_test.prj b/cores/curso/ch06/debounce_test.prj index 4fb2acf..95568d4 100644 --- a/cores/curso/ch06/debounce_test.prj +++ b/cores/curso/ch06/debounce_test.prj @@ -1,2 +1,3 @@ vhdl work "list_ch06_03_db_test.vhd" vhdl work "list_ch06_01_02_debounce.vhd" +vhdl work "../ch04/list_ch04_15_disp_hex.vhd" diff --git a/cores/curso/ch06/list_ch06_03_db_test.vhd b/cores/curso/ch06/list_ch06_03_db_test.vhd index 24d7b9c..7c76ad1 100644 --- a/cores/curso/ch06/list_ch06_03_db_test.vhd +++ b/cores/curso/ch06/list_ch06_03_db_test.vhd @@ -5,13 +5,15 @@ use ieee.numeric_std.all; entity debounce_test is port( clk: in std_logic; - btn: in std_logic_vector(3 downto 0); + bot: in std_logic_vector(4 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 debounce_test; architecture arch of debounce_test is + signal btn: std_logic_vector(3 downto 0); signal q1_reg, q1_next: unsigned(7 downto 0); signal q0_reg, q0_next: unsigned(7 downto 0); signal b_count, d_count: std_logic_vector(7 downto 0); @@ -19,6 +21,9 @@ architecture arch of debounce_test is signal db_tick, btn_tick, clr: std_logic; -- Listing 7.3 begin + + btn <= not bot(3 downto 0); + led <= not bot; -- instantiate debouncing circuit db_unit: entity work.debounce(fsmd_arch) port map( @@ -31,7 +36,8 @@ begin clk=>clk, reset=>'0', hex3=>b_count(7 downto 4), hex2=>b_count(3 downto 0), hex1=>d_count(7 downto 4), hex0=>d_count(3 downto 0), - dp_in=>"1011", an=>an, sseg=>sseg + point=>'1', colon=>'0', + an=>an, sseg=>sseg ); --================================================= diff --git a/cores/curso/ch07/ch07_zxuno_v4.ucf b/cores/curso/ch07/ch07_zxuno_v4.ucf new file mode 100644 index 0000000..c4756f0 --- /dev/null +++ b/cores/curso/ch07/ch07_zxuno_v4.ucf @@ -0,0 +1,44 @@ +#======================================================== +# clock +#======================================================== +NET "clk" LOC="P55" | IOSTANDARD=LVCMOS33; + +#======================================================== +# buttons & uart pins +#======================================================== +# 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 + +# 2 wire uart pins +NET "rx" LOC="P5" | IOSTANDARD=LVCMOS33 | PULLUP; #down +NET "tx" LOC="P2" | IOSTANDARD=LVCMOS33 | PULLUP; #fire + +#======================================================== +# 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/ch07/list_ch07_01_uart_rx.vhd b/cores/curso/ch07/list_ch07_01_uart_rx.vhd new file mode 100644 index 0000000..f240632 --- /dev/null +++ b/cores/curso/ch07/list_ch07_01_uart_rx.vhd @@ -0,0 +1,91 @@ +-- Listing 7.1 +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +entity uart_rx is + generic( + DBIT: integer:=8; -- # data bits + SB_TICK: integer:=16 -- # ticks for stop bits + ); + port( + clk, reset: in std_logic; + rx: in std_logic; + s_tick: in std_logic; + rx_done_tick: out std_logic; + dout: out std_logic_vector(7 downto 0) + ); +end uart_rx ; + +architecture arch of uart_rx is + type state_type is (idle, start, data, stop); + signal state_reg, state_next: state_type; + signal s_reg, s_next: unsigned(3 downto 0); + signal n_reg, n_next: unsigned(2 downto 0); + signal b_reg, b_next: std_logic_vector(7 downto 0); +begin + -- FSMD state & data registers + process(clk,reset) + begin + if reset='1' then + state_reg <= idle; + s_reg <= (others=>'0'); + n_reg <= (others=>'0'); + b_reg <= (others=>'0'); + elsif (clk'event and clk='1') then + state_reg <= state_next; + s_reg <= s_next; + n_reg <= n_next; + b_reg <= b_next; + end if; + end process; + -- next-state logic & data path functional units/routing + process(state_reg,s_reg,n_reg,b_reg,s_tick,rx) + begin + state_next <= state_reg; + s_next <= s_reg; + n_next <= n_reg; + b_next <= b_reg; + rx_done_tick <='0'; + case state_reg is + when idle => + if rx='0' then + state_next <= start; + s_next <= (others=>'0'); + end if; + when start => + if (s_tick = '1') then + if s_reg=7 then + state_next <= data; + s_next <= (others=>'0'); + n_next <= (others=>'0'); + else + s_next <= s_reg + 1; + end if; + end if; + when data => + if (s_tick = '1') then + if s_reg=15 then + s_next <= (others=>'0'); + b_next <= rx & b_reg(7 downto 1) ; + if n_reg=(DBIT-1) then + state_next <= stop ; + else + n_next <= n_reg + 1; + end if; + else + s_next <= s_reg + 1; + end if; + end if; + when stop => + if (s_tick = '1') then + if s_reg=(SB_TICK-1) then + state_next <= idle; + rx_done_tick <='1'; + else + s_next <= s_reg + 1; + end if; + end if; + end case; + end process; + dout <= b_reg; +end arch; \ No newline at end of file diff --git a/cores/curso/ch07/list_ch07_02_flag.vhd b/cores/curso/ch07/list_ch07_02_flag.vhd new file mode 100644 index 0000000..4cb6c0d --- /dev/null +++ b/cores/curso/ch07/list_ch07_02_flag.vhd @@ -0,0 +1,45 @@ +-- Listing 7.2 +library ieee; +use ieee.std_logic_1164.all; +entity flag_buf is + generic(W: integer:=8); + port( + clk, reset: in std_logic; + clr_flag, set_flag: in std_logic; + din: in std_logic_vector(W-1 downto 0); + dout: out std_logic_vector(W-1 downto 0); + flag: out std_logic + ); +end flag_buf; + +architecture arch of flag_buf is + signal buf_reg, buf_next: std_logic_vector(W-1 downto 0); + signal flag_reg, flag_next: std_logic; +begin + -- FF & register + process(clk,reset) + begin + if reset='1' then + buf_reg <= (others=>'0'); + flag_reg <= '0'; + elsif (clk'event and clk='1') then + buf_reg <= buf_next; + flag_reg <= flag_next; + end if; + end process; + -- next-state logic + process(buf_reg,flag_reg,set_flag,clr_flag,din) + begin + buf_next <= buf_reg; + flag_next <= flag_reg; + if (set_flag='1') then + buf_next <= din; + flag_next <= '1'; + elsif (clr_flag='1') then + flag_next <= '0'; + end if; + end process; + -- output logic + dout <= buf_reg; + flag <= flag_reg; +end arch; diff --git a/cores/curso/ch07/list_ch07_03_uart_tx.vhd b/cores/curso/ch07/list_ch07_03_uart_tx.vhd new file mode 100644 index 0000000..80e19f0 --- /dev/null +++ b/cores/curso/ch07/list_ch07_03_uart_tx.vhd @@ -0,0 +1,102 @@ +-- Listing 7.3 +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +entity uart_tx is + generic( + DBIT: integer:=8; -- # data bits + SB_TICK: integer:=16 -- # ticks for stop bits + ); + port( + clk, reset: in std_logic; + tx_start: in std_logic; + s_tick: in std_logic; + din: in std_logic_vector(7 downto 0); + tx_done_tick: out std_logic; + tx: out std_logic + ); +end uart_tx ; + +architecture arch of uart_tx is + type state_type is (idle, start, data, stop); + signal state_reg, state_next: state_type; + signal s_reg, s_next: unsigned(3 downto 0); + signal n_reg, n_next: unsigned(2 downto 0); + signal b_reg, b_next: std_logic_vector(7 downto 0); + signal tx_reg, tx_next: std_logic; +begin + -- FSMD state & data registers + process(clk,reset) + begin + if reset='1' then + state_reg <= idle; + s_reg <= (others=>'0'); + n_reg <= (others=>'0'); + b_reg <= (others=>'0'); + tx_reg <= '1'; + elsif (clk'event and clk='1') then + state_reg <= state_next; + s_reg <= s_next; + n_reg <= n_next; + b_reg <= b_next; + tx_reg <= tx_next; + end if; + end process; + -- next-state logic & data path functional units/routing + process(state_reg,s_reg,n_reg,b_reg,s_tick, + tx_reg,tx_start,din) + begin + state_next <= state_reg; + s_next <= s_reg; + n_next <= n_reg; + b_next <= b_reg; + tx_next <= tx_reg ; + tx_done_tick <= '0'; + case state_reg is + when idle => + tx_next <= '1'; + if tx_start='1' then + state_next <= start; + s_next <= (others=>'0'); + b_next <= din; + end if; + when start => + tx_next <= '0'; + if (s_tick = '1') then + if s_reg=15 then + state_next <= data; + s_next <= (others=>'0'); + n_next <= (others=>'0'); + else + s_next <= s_reg + 1; + end if; + end if; + when data => + tx_next <= b_reg(0); + if (s_tick = '1') then + if s_reg=15 then + s_next <= (others=>'0'); + b_next <= '0' & b_reg(7 downto 1) ; + if n_reg=(DBIT-1) then + state_next <= stop ; + else + n_next <= n_reg + 1; + end if; + else + s_next <= s_reg + 1; + end if; + end if; + when stop => + tx_next <= '1'; + if (s_tick = '1') then + if s_reg=(SB_TICK-1) then + state_next <= idle; + tx_done_tick <= '1'; + else + s_next <= s_reg + 1; + end if; + end if; + end case; + end process; + tx <= tx_reg; +end arch; diff --git a/cores/curso/ch07/list_ch07_04_uart.vhd b/cores/curso/ch07/list_ch07_04_uart.vhd new file mode 100644 index 0000000..c07d060 --- /dev/null +++ b/cores/curso/ch07/list_ch07_04_uart.vhd @@ -0,0 +1,63 @@ +-- Listing 7.4 +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +entity uart is + generic( + -- Default setting: + -- 19,200 baud, 8 data bis, 1 stop its, 2^2 FIFO + DBIT: integer:=8; -- # data bits + SB_TICK: integer:=16; -- # ticks for stop bits, 16/24/32 + -- for 1/1.5/2 stop bits + DVSR: integer:= 163; -- baud rate divisor + -- DVSR = 50M/(16*baud rate) + DVSR_BIT: integer:=8; -- # bits of DVSR + FIFO_W: integer:=2 -- # addr bits of FIFO + -- # words in FIFO=2^FIFO_W + ); + port( + clk, reset: in std_logic; + rd_uart, wr_uart: in std_logic; + rx: in std_logic; + w_data: in std_logic_vector(7 downto 0); + tx_full, rx_empty: out std_logic; + r_data: out std_logic_vector(7 downto 0); + tx: out std_logic + ); +end uart; + +architecture str_arch of uart is + signal tick: std_logic; + signal rx_done_tick: std_logic; + signal tx_fifo_out: std_logic_vector(7 downto 0); + signal rx_data_out: std_logic_vector(7 downto 0); + signal tx_empty, tx_fifo_not_empty: std_logic; + signal tx_done_tick: std_logic; +begin + baud_gen_unit: entity work.mod_m_counter(arch) + generic map(M=>DVSR, N=>DVSR_BIT) + port map(clk=>clk, reset=>reset, + q=>open, max_tick=>tick); + uart_rx_unit: entity work.uart_rx(arch) + generic map(DBIT=>DBIT, SB_TICK=>SB_TICK) + port map(clk=>clk, reset=>reset, rx=>rx, + s_tick=>tick, rx_done_tick=>rx_done_tick, + dout=>rx_data_out); + fifo_rx_unit: entity work.fifo(arch) + generic map(B=>DBIT, W=>FIFO_W) + port map(clk=>clk, reset=>reset, rd=>rd_uart, + wr=>rx_done_tick, w_data=>rx_data_out, + empty=>rx_empty, full=>open, r_data=>r_data); + fifo_tx_unit: entity work.fifo(arch) + generic map(B=>DBIT, W=>FIFO_W) + port map(clk=>clk, reset=>reset, rd=>tx_done_tick, + wr=>wr_uart, w_data=>w_data, empty=>tx_empty, + full=>tx_full, r_data=>tx_fifo_out); + uart_tx_unit: entity work.uart_tx(arch) + generic map(DBIT=>DBIT, SB_TICK=>SB_TICK) + port map(clk=>clk, reset=>reset, + tx_start=>tx_fifo_not_empty, + s_tick=>tick, din=>tx_fifo_out, + tx_done_tick=> tx_done_tick, tx=>tx); + tx_fifo_not_empty <= not tx_empty; +end str_arch; \ No newline at end of file diff --git a/cores/curso/ch07/list_ch07_05_uart_test.vhd b/cores/curso/ch07/list_ch07_05_uart_test.vhd new file mode 100644 index 0000000..e81e37a --- /dev/null +++ b/cores/curso/ch07/list_ch07_05_uart_test.vhd @@ -0,0 +1,42 @@ +-- Listing 7.5 +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +entity uart_test is + port( + clk, reset: in std_logic; + bot: in std_logic_vector(2 downto 0); + rx: in std_logic; + tx: out std_logic; + led: out std_logic_vector(4 downto 0); + sseg: out std_logic_vector(7 downto 0); + an: out std_logic_vector(3 downto 0) + ); +end uart_test; + +architecture arch of uart_test is + signal btn: std_logic_vector(2 downto 0); + signal tx_full, rx_empty: std_logic; + signal rec_data,rec_data1: std_logic_vector(7 downto 0); + signal btn_tick: std_logic; +begin + + btn <= not bot; + + -- instantiate uart + uart_unit: entity work.uart(str_arch) + port map(clk=>clk, reset=>reset, rd_uart=>btn_tick, + wr_uart=>btn_tick, rx=>rx, w_data=>rec_data1, + tx_full=>tx_full, rx_empty=>rx_empty, + r_data=>rec_data, tx=>tx); + -- instantiate debounce circuit + btn_db_unit: entity work.debounce(fsmd_arch) + port map(clk=>clk, reset=>reset, sw=>btn(0), + db_level=>open, db_tick=>btn_tick); + -- incremented data loop back + rec_data1 <= std_logic_vector(unsigned(rec_data)+1); + -- led display + led <= rec_data(4 downto 0); + an <= "1110"; + sseg <= '1' & (not tx_full) & "11" & (not rx_empty) & "111"; +end arch; diff --git a/cores/curso/ch07/make.bat b/cores/curso/ch07/make.bat new file mode 100644 index 0000000..3104996 --- /dev/null +++ b/cores/curso/ch07/make.bat @@ -0,0 +1,12 @@ +SET speed=2 +SET ruta_ucf=ch07 +SET ruta_bat=..\..\ +call :genbitstream debounce_test +goto :eof + +:genbitstream +SET machine=%1 +call %ruta_bat%genxst.bat +call %ruta_bat%generar.bat v4 ZX1 +copy /y COREn.ZX1 %ruta_ucf%_%machine%.ZX1 +goto :eof diff --git a/cores/curso/ch07/timings.xcf b/cores/curso/ch07/timings.xcf new file mode 100644 index 0000000..7ce464f --- /dev/null +++ b/cores/curso/ch07/timings.xcf @@ -0,0 +1,2 @@ +# Timing constraints +NET "clk" PERIOD=20 ns; diff --git a/cores/curso/ch07/uart_test.prj b/cores/curso/ch07/uart_test.prj new file mode 100644 index 0000000..d60ba06 --- /dev/null +++ b/cores/curso/ch07/uart_test.prj @@ -0,0 +1,6 @@ +vhdl work "list_ch07_05_uart_test.vhd" +vhdl work "list_ch07_04_uart.vhd" +vhdl work "list_ch07_03_uart_tx.vhd" +vhdl work "list_ch07_01_uart_rx.vhd" +vhdl work "../ch06/list_ch06_01_02_debounce.vhd" +vhdl work "../ch04/list_ch04_20_fifo.vhd" diff --git a/cores/curso/ch07/uart_test.ut b/cores/curso/ch07/uart_test.ut new file mode 100644 index 0000000..a9facca --- /dev/null +++ b/cores/curso/ch07/uart_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/ch07/uart_test.xst b/cores/curso/ch07/uart_test.xst new file mode 100644 index 0000000..e066ba2 --- /dev/null +++ b/cores/curso/ch07/uart_test.xst @@ -0,0 +1,53 @@ +set -tmpdir "projnav.tmp" +set -xsthdpdir "xst" +run +-ifn uart_test.prj +-infer_ramb8 No -loop_iteration_limit 32768 +-ofn uart_test +-ofmt NGC +-p xc6slx9-2-tqg144 +-top uart_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