]> rtime.felk.cvut.cz Git - fpga/spartan2/qcounter.git/commitdiff
Complete design added.
authorVladimir Burian <buriavl2@fel.cvut.cz>
Fri, 4 Feb 2011 21:25:06 +0000 (22:25 +0100)
committerVladimir Burian <buriavl2@fel.cvut.cz>
Sat, 5 Feb 2011 13:23:06 +0000 (14:23 +0100)
Makefile [new file with mode: 0644]
div_20.vhd [new file with mode: 0644]
hex2lcd.vhd [new file with mode: 0644]
lcd_mux.vhd [new file with mode: 0644]
top_counter.prj [new file with mode: 0644]
top_counter.ucf [new file with mode: 0644]
top_counter.vhd [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..947398a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,151 @@
+# TOP           - Name of the top-level module
+# DEVICE        - Name of the FPGA device (device-package-speed)
+# PRJ           - Name of .prj file with names of all source files. See XST manual.
+# BMM           - If design contains initialized memories, softcore MCU, etc., this
+#                 file describes mapping of .elf file to these memories. Only one
+#                 .bmm file can be used.
+# ELF           - File containing initialization data of memories described by
+#                 previously defined .bmm file. Format can be .elf or .mem.
+# SEARCH_DIRS   - Directories to search when searching for netlists (.ngc, ...).
+#                 See NGDBUILD manual.
+# JTAG_POS      - Position of device in JTAG chain. Used when downloading bit stream.
+# INTSTYLE      - Style of screen output. (ise | xflow | silent)
+
+
+TOP             = top_counter
+DEVICE          = xc2s100-pq208
+
+PRJ            = top_counter.prj
+
+BMM             = 
+ELF             = 
+
+SEARCH_DIRS     = 
+
+NGDBUILG_FLAGS  = -aul      # Allow Unmatched LOCs
+
+
+JTAG_POS        = 2
+INTSTYLE        = xflow
+
+# NOTICE: Impact when using in batch mode won't download bitfile to the
+# FPGA. Solution I found is to call 'program -p 1' at the end of the
+# procedure. See 'download' target.
+
+ifneq (${strip ${BMM}},)
+  BITFILE = ${TOP}_rp.bit
+else
+  BITFILE = ${TOP}.bit
+endif
+
+#===============================================================================
+
+.PHONY: all synth ngdbuild map implement download clean
+
+all: clean implement
+
+implement: ${BITFILE}
+
+#===============================================================================
+
+synth ${TOP}.ngc: ${PRJ}
+       echo " \
+               run \
+               ${addprefix -ifn ,${PRJ}} \
+               -ifmt mixed \
+               -ofn ${TOP}.ngc \
+               -ofmt NGC \
+               -top ${TOP} \
+               -p ${DEVICE} \
+               -opt_mode Speed \
+               -opt_level 1" \
+       | xst
+
+
+ngdbuild ${TOP}.ngd: ${TOP}.ngc ${BMM} ${TOP}.ucf
+       ngdbuild \
+               ${addprefix -bm ,${BMM}} \
+               -intstyle ${INTSTYLE} \
+               -aul \
+               -p ${DEVICE} \
+               -uc ${TOP}.ucf \
+               ${addprefix -sd ,${SEARCH_DIRS}} \
+               ${TOP}.ngc \
+               ${TOP}.ngd
+
+
+map ${TOP}.ncd: ${TOP}.ngd
+       map \
+               -p ${DEVICE} \
+               -intstyle ${INTSTYLE} \
+               ${TOP}.ngd \
+               ${TOP}.pcf
+       par \
+               -w ${TOP}.ncd \
+               -intstyle ${INTSTYLE} \
+               ${TOP}.ncd \
+               ${TOP}.pcf
+
+
+${TOP}.bit: ${TOP}.ncd
+       bitgen -w ${TOP}.ncd ${TOP}.bit ${TOP}.pcf
+
+${TOP}_rp.bit: ${TOP}.bit ${ELF}
+       data2mem -bm ${basename ${BMM}}_bd.bmm -bd ${ELF} -bt ${TOP}.bit -o b ${TOP}_rp.bit
+
+download: ${BITFILE}
+       /bin/echo -e "\
+       setMode -bscan \n\
+       cleancablelock \n\
+       setCable -port auto \n\
+       identify \n\
+       assignFile -p ${JTAG_POS} -file ${BITFILE} \n\
+       program -p ${JTAG_POS} \n\
+       program -p 1 \n\
+       exit" | impact -batch
+
+#===============================================================================
+
+clean:
+       rm -f _impactbatch.log
+       rm -f ${basename ${BMM}}_bd.bmm
+       rm -f netlist.lst
+       rm -f ${TOP}.bgn
+       rm -f ${TOP}.bit
+       rm -f ${TOP}.bld
+       rm -f ${TOP}.d
+       rm -f ${TOP}.drc
+       rm -f ${TOP}.lso
+       rm -f ${TOP}.map
+       rm -f ${TOP}.mrp
+       rm -f ${TOP}.ncd
+       rm -f ${TOP}.ngc
+       rm -f ${TOP}.ngd
+       rm -f ${TOP}.ngm
+       rm -f ${TOP}.pad
+       rm -f ${TOP}_pad.csv
+       rm -f ${TOP}_pad.txt
+       rm -f ${TOP}.par
+       rm -f ${TOP}.pcf
+       rm -f ${TOP}_rp.bit
+       rm -f ${TOP}_summary.xml
+       rm -f ${TOP}.unroutes
+       rm -f ${TOP}_usage.xml
+       rm -f ${TOP}.xpi
+       rm -rf xst
+
+#===============================================================================
+
+%.d: %.prj
+       sed -e 's/#.*//' \
+       -e 's/[ \t][ \t]*/ /g' \
+       -e 's/"//g' \
+       -e 's/^ //' -e 's/ $$//' \
+       -e 's|\(.*\) \(.*\) \(.*\)|$<: \3|' \
+       <$< >$@
+
+%.prj:
+       touch $@
+
+include ${PRJ:.prj=.d}
+
diff --git a/div_20.vhd b/div_20.vhd
new file mode 100644 (file)
index 0000000..a5af207
--- /dev/null
@@ -0,0 +1,35 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_ARITH.all;
+use IEEE.STD_LOGIC_UNSIGNED.all;
+
+--------------------------------------------------------------------------------
+-- This module divides the incoming clock by 2^20 and outputs the 20th bit of
+-- the counter as clk_2k.
+--------------------------------------------------------------------------------
+
+entity div_20 is
+  port (
+    clk    : in  std_logic;
+    clk_2k : out std_logic);
+end div_20;
+
+--------------------------------------------------------------------------------
+
+architecture Behavioral of div_20 is
+  
+  signal count : std_logic_vector (19 downto 0);
+  
+begin
+  
+  process(clk)
+  begin
+    if(clk'event and clk = '1') then
+      count <= count + "00000000000000000001";
+    end if;
+  end process;
+
+  clk_2k <= count(19);
+  
+end Behavioral;
+
diff --git a/hex2lcd.vhd b/hex2lcd.vhd
new file mode 100644 (file)
index 0000000..0ac1b72
--- /dev/null
@@ -0,0 +1,41 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_ARITH.all;
+use IEEE.STD_LOGIC_UNSIGNED.all;
+
+--------------------------------------------------------------------------------
+-- This module implements combinatorial circuit converting a 4 digit binary
+-- number into the format of display segments.
+--------------------------------------------------------------------------------
+
+entity hex2lcd is
+  port (
+    hex : in  std_logic_vector (3 downto 0);
+    lcd : out std_logic_vector (6 downto 0));
+end hex2lcd;
+
+--------------------------------------------------------------------------------
+
+architecture behavioral of hex2lcd is
+begin
+  
+  with hex select lcd <=
+    "0000110" when "0001",
+    "1011011" when "0010",
+    "1001111" when "0011",
+    "1100110" when "0100",
+    "1101101" when "0101",
+    "1111101" when "0110",
+    "0000111" when "0111",
+    "1111111" when "1000",
+    "1101111" when "1001",
+    "1110111" when "1010",
+    "1111100" when "1011",
+    "0111001" when "1100",
+    "1011110" when "1101",
+    "1111001" when "1110",
+    "1110001" when "1111",
+    "0111111" when others;
+  
+end Behavioral;
+
diff --git a/lcd_mux.vhd b/lcd_mux.vhd
new file mode 100644 (file)
index 0000000..0de18b9
--- /dev/null
@@ -0,0 +1,53 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_ARITH.all;
+use IEEE.STD_LOGIC_UNSIGNED.all;
+
+--------------------------------------------------------------------------------
+-- This module controls the bias reversal for a single 7-segment display. The
+-- clk input xor's the segment data to cause the segment biasing to be swapped.
+-- The cnt signal should be about 20-30 Hz for LCD to function correctly. The
+-- common signal is also bias reversed at this same frequency.
+--
+-- Example: A is off and B is on, COM is driven by clk signal.
+--         __    __    __    __ 
+--   A  __|  |__|  |__|  |__|  |__
+--      __    __    __    __    __
+--   B    |__|  |__|  |__|  |__|  
+--         __    __    __    __ 
+-- COM  __|  |__|  |__|  |__|  |__
+--
+--------------------------------------------------------------------------------
+
+entity lcd_mux is
+  port (
+    clk     : in  std_logic;
+    cnt     : in  std_logic;
+    data_in : in  std_logic_vector (6 downto 0);
+    lcd_seg : out std_logic_vector (6 downto 0);
+    lcd_com : out std_logic;
+    lcd_dp  : out std_logic);
+end lcd_mux;
+
+--------------------------------------------------------------------------------
+
+architecture behavioral of lcd_mux is
+begin
+  
+  process (clk)
+  begin
+    if (clk'event and clk = '1') then
+      lcd_seg(0) <= data_in(0) xor cnt;
+      lcd_seg(1) <= data_in(1) xor cnt;
+      lcd_seg(2) <= data_in(2) xor cnt;
+      lcd_seg(3) <= data_in(3) xor cnt;
+      lcd_seg(4) <= data_in(4) xor cnt;
+      lcd_seg(5) <= data_in(5) xor cnt;
+      lcd_seg(6) <= data_in(6) xor cnt;
+      lcd_com    <= cnt;
+      lcd_dp     <= '0' xor cnt;
+    end if;
+  end process;
+  
+end Behavioral;
+
diff --git a/top_counter.prj b/top_counter.prj
new file mode 100644 (file)
index 0000000..8687177
--- /dev/null
@@ -0,0 +1,9 @@
+vhdl work quadcount/dff.vhdl
+vhdl work quadcount/qcounter.vhdl
+
+vhdl work lcd_mux.vhd
+vhdl work hex2lcd.vhd
+vhdl work div_20.vhd
+
+vhdl work top_counter.vhd
+
diff --git a/top_counter.ucf b/top_counter.ucf
new file mode 100644 (file)
index 0000000..9c09dc3
--- /dev/null
@@ -0,0 +1,83 @@
+#==============================================================================#
+# Pin constraints of Spartan-II Demo Board made by Insight                     #
+#==============================================================================#
+
+#==============================================================================#
+# Clock & Reset                                                                #
+#==============================================================================#
+# I have measured clock frequency 40.38 MHz
+# Oscilator chip DS1073 is shipped from the factory configured for half the 
+# maximum operating frequency. And can be reconfigured using 1-wire protocol in
+# the range of approximately 30kHz to 1000MHz.
+
+NET "clk"             LOC = "P80" |   PERIOD = 24 ns;
+NET "reset"           LOC = "P206";
+
+#==============================================================================#
+# LCD display                                                                  #
+#==============================================================================#
+
+NET "lcd_com"         LOC = "P174";
+
+NET "lcd2<0>"         LOC = "P168";
+NET "lcd2<1>"         LOC = "P166";
+NET "lcd2<2>"         LOC = "P165";
+NET "lcd2<3>"         LOC = "P163";
+NET "lcd2<4>"         LOC = "P162";
+NET "lcd2<5>"         LOC = "P172";
+NET "lcd2<6>"         LOC = "P173";
+NET "lcd2_dp"         LOC = "P161";
+
+NET "lcd1<0>"         LOC = "P187";
+NET "lcd1<1>"         LOC = "P181";
+NET "lcd1<2>"         LOC = "P180";
+NET "lcd1<3>"         LOC = "P179";
+NET "lcd1<4>"         LOC = "P176";
+NET "lcd1<5>"         LOC = "P188";
+NET "lcd1<6>"         LOC = "P191";
+NET "lcd1_dp"         LOC = "P175";
+
+#==============================================================================#
+# RS-232 communication port                                                    #
+#==============================================================================#
+# TXD is input to the board.
+# RXD is output from the board.
+
+NET "txd"             LOC = "P193";
+NET "rxd"             LOC = "P194";
+
+#==============================================================================#
+# LEDs                                                                         #
+#==============================================================================#
+# All LEDs are low active.
+
+NET "led4"            LOC = "P195";
+NET "led5"            LOC = "P199";
+NET "led6"            LOC = "P201";
+
+#==============================================================================#
+# DIP switches                                                                 #
+#==============================================================================#
+# All switches are low active.
+
+NET "sw1"             LOC = "P202";
+NET "sw2"             LOC = "P204";
+NET "sw3"             LOC = "P205";
+NET "sw4"             LOC = "P206";
+
+
+#==============================================================================#
+# Other connected devices                                                      #
+#==============================================================================#
+
+#Rotary encoder connect to the header JP1.
+# rot_feed  - JP1.1 - log. 1 "feeding" quadratic encoder
+# rot_A     - JP1.3
+# rot_B     - JP1.5
+# rot_press - JPJ.7 - quadratic encoder has also function of button
+
+NET "rot_feed"        LOC = "P3";
+NET "rot_A"           LOC = "P5" |    PULLDOWN;
+NET "rot_B"           LOC = "P7" |    PULLDOWN; 
+NET "rot_press"       LOC = "P9" |    PULLDOWN;
+
diff --git a/top_counter.vhd b/top_counter.vhd
new file mode 100644 (file)
index 0000000..7a0918a
--- /dev/null
@@ -0,0 +1,135 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_ARITH.all;
+use IEEE.STD_LOGIC_UNSIGNED.all;
+
+--------------------------------------------------------------------------------
+-- This is the top module instantiating quadratic counter with output to the
+-- on-board LCD. See 'top_counter.ucf' and read how a quadratic encoder is
+-- connected.
+--------------------------------------------------------------------------------
+
+entity top_counter is
+  port(
+    clk       : in  std_logic;
+    reset     : in  std_logic;
+    
+    rot_A     : in  std_logic;
+    rot_B     : in  std_logic;
+    rot_press : in  std_logic;
+    rot_feed  : out std_logic;
+    
+    lcd_com   : out std_logic;
+    lcd2_dp   : out std_logic;
+    lcd1_dp   : out std_logic;
+    lcd1      : out std_logic_vector(6 downto 0);
+    lcd2      : out std_logic_vector(6 downto 0));
+end top_counter;
+
+--------------------------------------------------------------------------------
+
+architecture behavioral of top_counter is
+  
+  component div_20 is
+    port (
+      clk    : in  std_logic;
+      clk_2k : out std_logic);
+  end component;
+
+  component hex2lcd is
+    port (
+      hex : in  std_logic_vector (3 downto 0);
+      lcd : out std_logic_vector (6 downto 0));
+  end component;
+
+  component lcd_mux is
+    port (
+      clk     : in  std_logic;
+      cnt     : in  std_logic;
+      data_in : in  std_logic_vector (6 downto 0);
+      lcd_seg : out std_logic_vector (6 downto 0);
+      lcd_com : out std_logic;
+      lcd_dp  : out std_logic);
+  end component;
+
+  component qcounter is
+    port (
+      clock    : in  std_logic;
+      reset    : in  std_logic;
+      a0, b0   : in  std_logic;
+      qcount   : out std_logic_vector (31 downto 0);
+      a_rise   : out std_logic;
+      a_fall   : out std_logic;
+      b_rise   : out std_logic;
+      b_fall   : out std_logic;
+      ab_event : out std_logic;
+      ab_error : out std_logic);
+  end component;
+
+
+  signal lcd_clk  : std_logic;
+  signal lcd1_out : std_logic_vector (6 downto 0);
+  signal lcd2_out : std_logic_vector (6 downto 0);
+
+  signal qcount_data  : std_logic_vector (31 downto 0);
+  signal qcount_reset : std_logic;
+
+--------------------------------------------------------------------------------
+  
+begin
+  
+  div_20_1 : div_20
+    port map (
+      clk    => clk,
+      clk_2k => lcd_clk);
+
+  hex2lcd_1 : hex2lcd
+    port map (
+      hex => qcount_data(5 downto 2),
+      lcd => lcd1_out);
+
+  hex2lcd_2 : hex2lcd
+    port map (
+      hex => qcount_data(9 downto 6),
+      lcd => lcd2_out);
+
+  lcd_mux_1 : lcd_mux
+    port map (
+      clk     => clk,
+      cnt     => lcd_clk,
+      data_in => lcd1_out,
+      lcd_seg => lcd1,
+      lcd_com => lcd_com,
+      lcd_dp  => lcd1_dp);
+
+  lcd_mux_2 : lcd_mux
+    port map (
+      clk     => clk,
+      cnt     => lcd_clk,
+      data_in => lcd2_out,
+      lcd_seg => lcd2,
+      lcd_com => open,
+      lcd_dp  => lcd2_dp);
+
+  qcounter_1 : qcounter
+    port map (
+      clock    => clk,
+      reset    => qcount_reset,
+      a0       => rot_A,
+      b0       => rot_B,
+      qcount   => qcount_data,
+      a_rise   => open,
+      a_fall   => open,
+      b_rise   => open,
+      b_fall   => open,
+      ab_event => open,
+      ab_error => open);
+
+--------------------------------------------------------------------------------
+
+  rot_feed <= '1';
+
+  qcount_reset <= not reset or rot_press;
+  
+end Behavioral;
+