]> rtime.felk.cvut.cz Git - fpga/virtex2/uart.git/blobdiff - omsp_quadcount.vhd
Added custom openMSP430 peripheral as an interface to the quadcount module.
[fpga/virtex2/uart.git] / omsp_quadcount.vhd
diff --git a/omsp_quadcount.vhd b/omsp_quadcount.vhd
new file mode 100644 (file)
index 0000000..e334f41
--- /dev/null
@@ -0,0 +1,73 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+entity omsp_quadcount is
+  port (
+    mclk        : in  std_logic;
+    per_addr    : in  std_logic_vector (7  downto 0);
+    per_din     : in  std_logic_vector (15 downto 0);  -- unused
+    per_en      : in  std_logic;
+    per_wen     : in  std_logic_vector (1  downto 0);  -- unused
+    puc         : in  std_logic;                       -- unused
+    per_irq_acc : in  std_logic;                       -- unused
+    per_irq     : out std_logic;                       -- unused
+    per_dout    : out std_logic_vector (15 downto 0);
+    
+    qcount      : in  std_logic_vector (31 downto 0)
+  );
+end omsp_quadcount;
+
+--------------------------------------------------------------------------------
+
+architecture behavioral of omsp_quadcount is
+
+  -- When reading whole 32-bit qcount input, first QCNTL has to be loaded, because
+  -- this event causes QCNTH to latch appropriate value of qcount. This procedure
+  -- ensures that correct value is readed.
+  constant QCNTL : std_logic_vector (15 downto 0) := X"0150";  -- qcount lower word logic address
+  constant QCNTH : std_logic_vector (15 downto 0) := X"0152";  -- qcount higher word logic address
+
+  signal qcntl_sel : boolean;
+  signal qcnth_sel : boolean;
+
+  signal qcnth_latch : std_logic_vector (15 downto 0) := (others => '0');
+
+  signal qcount_prev : std_logic_vector (31 downto 0) := (others => '0');
+
+--------------------------------------------------------------------------------
+
+begin
+
+  qcntl_sel <= (per_addr = QCNTL(8 downto 1)) and (per_en = '1');
+  qcnth_sel <= (per_addr = QCNTH(8 downto 1)) and (per_en = '1');
+
+  per_dout <= qcount (15 downto 0) when qcntl_sel else
+              qcnth_latch          when qcnth_sel else
+              (others => '0');
+
+
+  process (mclk)
+  begin
+    if (rising_edge(mclk) and qcntl_sel) then
+      qcnth_latch <= qcount (31 downto 16);
+    end if;
+  end process;
+
+  -- Generation of IRQ signal. (changes in lower 2 bits are suppresed)
+  process (mclk)
+  begin
+    if (rising_edge(mclk)) then
+      qcount_prev <= qcount;
+      
+      if (qcntl_sel) then
+        per_irq <= '0';
+      elsif (qcount_prev (31 downto 2) /= qcount (31 downto 2)) then
+        per_irq <= '1';
+      end if;
+    end if;
+  end process;
+
+end behavioral;
+