]> rtime.felk.cvut.cz Git - fpga/virtex2/uart.git/commitdiff
+ PWM output capability.
authorVladimir Burian <buriavl2@fel.cvut.cz>
Sat, 12 Feb 2011 22:46:34 +0000 (23:46 +0100)
committerVladimir Burian <buriavl2@fel.cvut.cz>
Sun, 13 Feb 2011 12:46:28 +0000 (13:46 +0100)
Added 2 new entities: counter and omsp_pwm.
Instances of these are inserted in the top-level.

counter.vhd [new file with mode: 0644]
omsp_pwm.vhd [new file with mode: 0644]
openMSP430_uart.prj
openMSP430_uart.ucf
openMSP430_uart.vhd

diff --git a/counter.vhd b/counter.vhd
new file mode 100644 (file)
index 0000000..cfb698a
--- /dev/null
@@ -0,0 +1,49 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+
+--------------------------------------------------------------------------------
+-- General counter which count width and maximum value can be set by generic
+-- attributes.
+--------------------------------------------------------------------------------
+
+entity counter is
+  generic (
+    WIDTH : integer := 16;
+    MAX   : integer := 2**16 - 1);
+  port (
+    clk   : in  std_logic;
+    reset : in  std_ulogic;
+    count : out std_logic_vector (WIDTH-1 downto 0));
+end counter;
+
+--------------------------------------------------------------------------------
+
+architecture behavioral of counter is
+
+  signal cnt : std_logic_vector (WIDTH-1 downto 0);
+
+--------------------------------------------------------------------------------
+
+begin
+
+  count <= cnt;
+  
+  
+  process (clk, reset) is
+  begin
+    if reset = '1' then
+      cnt <= (others => '0');
+
+    elsif clk'event and clk = '1' then
+      if cnt = CONV_STD_LOGIC_VECTOR(MAX, WIDTH) then
+        cnt <= (others => '0');
+      else
+        cnt <= cnt + 1;
+      end if;
+    end if;
+  end process;
+
+end behavioral;
+
diff --git a/omsp_pwm.vhd b/omsp_pwm.vhd
new file mode 100644 (file)
index 0000000..24afa76
--- /dev/null
@@ -0,0 +1,96 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+
+--------------------------------------------------------------------------------
+-- This entity is a generator of PWM signal with 16-bit MCU interface.
+--
+-- PWM bit width is configurable by PWM_WIDTH generic parameter and must be in
+-- range of 1 to 16. Default is 16.
+--
+-- In practice, to generate PWM signal component must be fed by a counter vector
+-- (pwm_cnt input) of appropriate width and also period! (One counter can be
+-- used by several PWM generators and generated signals are then synchronized.)
+--
+-- The period of the input counter vector should be by 1 smaller than the count
+-- of all possible PWM values, i.e. counter vector should never reaches the
+-- maximum possible PWM value, and counting should start from 0. E.g. when full
+-- range of PWM values is used, binary counter should be reset just one step
+-- before it overflows. In such a case, when PWM value is maximal, output keeps
+-- log. 1.
+--
+-- MCU interface consist of one r/w 16-bit register holding PWM value.
+--------------------------------------------------------------------------------
+
+entity omsp_pwm is
+  generic (
+    ADDR      : integer := 16#0160#;
+    PWM_WIDTH : integer := 16);
+  port (
+    -- MCU peripheral interface
+    mclk     : in  std_logic;
+    puc      : in  std_logic;
+    per_addr : in  std_logic_vector (7 downto 0);
+    per_en   : in  std_logic;
+    per_wen  : in  std_logic_vector (1 downto 0);
+    per_din  : in  std_logic_vector (15 downto 0);
+    per_dout : out std_logic_vector (15 downto 0);
+    -- PWM interface
+    pwm_cnt  : in  std_logic_vector (PWM_WIDTH-1 downto 0);
+    pwm      : out std_logic);
+end omsp_pwm;
+
+--------------------------------------------------------------------------------
+
+architecture behavioral of omsp_pwm is
+
+  signal pwm_value : std_logic_vector (15 downto 0);
+  
+  signal pwm_sel : boolean;
+  
+--------------------------------------------------------------------------------
+
+begin
+
+  pwm_sel <= (per_addr = ADDR/2) and (per_en = '1');
+
+  per_dout <= pwm_value when pwm_sel else
+              (others => '0');
+  
+
+  -- Peripheral registers
+  process (mclk, puc)
+  begin
+    if puc = '1' then
+      pwm_value <= (others => '0');
+
+    elsif rising_edge(mclk) and pwm_sel then
+      if per_wen (0) = '1' then
+        pwm_value (7 downto 0) <= per_din (7 downto 0);
+      end if;
+      
+      if per_wen (1) = '1' then
+        pwm_value (15 downto 8) <= per_din (15 downto 8);
+      end if;
+    end if;
+  end process;
+
+
+  -- Generation of the PWM signal
+  process (mclk, puc)
+  begin
+    if puc = '1' then
+      pwm <= '0';
+      
+    elsif mclk'event and mclk = '1' then
+      if pwm_cnt < pwm_value then
+        pwm <= '1';
+      else
+        pwm <= '0';
+      end if;
+    end if;
+  end process;
+
+end behavioral;
+
index 5d3418bd2bd7ff6e4d8b7cb646b081a70a6a2015..6d4283c5d0311e67dce816d44e90c25f14ec232a 100644 (file)
@@ -24,6 +24,9 @@ vhdl work uart/fifo.vhd
 vhdl work uart/baud_gen.vhd
 vhdl work uart/uart.vhd
 
+vhdl work counter.vhd
+vhdl work omsp_pwm.vhd
+
 vhdl work omsp_quadcount.vhd
 vhdl work quadcount/dff.vhdl
 vhdl work quadcount/qcounter.vhdl
index e28d6b55dcddfd0bef00ca09c9a9d6a9d12f564e..a17400a21179e264a83c226fac133f23db334841 100644 (file)
@@ -24,3 +24,10 @@ NET "ROT_A"             LOC = "J2"    | PULLDOWN;   # pin 03
 NET "ROT_B"             LOC = "K2"    | PULLDOWN;   # pin 05
 NET "ROT_PRESS"         LOC = "E4"    | PULLDOWN;   # pin 07
 
+#==============================================================================#
+# PWM output                                                                   #
+#==============================================================================#
+# Connected to the header J7 (LVDS TX STATUS).
+
+NET "PWM"               LOC = "C1";                 # pin 01
+
index bdd92f6c764508fecc6713f9938c8b9b55959141..7537c6f64c7e9f7cf3eb4915f3968f5a8faa9af6 100644 (file)
@@ -14,7 +14,9 @@ entity openMSP430_uart is
     ROT_FEED : out std_logic;
     ROT_A : in std_logic;
     ROT_B : in std_logic;
-    ROT_PRESS : in std_logic
+    ROT_PRESS : in std_logic;
+
+    PWM : out std_logic
   );
 end openMSP430_uart;
 
@@ -110,6 +112,33 @@ architecture rtl of openMSP430_uart is
     );
   end component;
 
+  component omsp_pwm is
+    generic (
+      ADDR      : integer;
+      PWM_WIDTH : integer);
+    port (
+      mclk     : in  std_logic;
+      puc      : in  std_logic;
+      per_addr : in  std_logic_vector (7 downto 0);
+      per_en   : in  std_logic;
+      per_wen  : in  std_logic_vector (1 downto 0);
+      per_din  : in  std_logic_vector (15 downto 0);
+      per_dout : out std_logic_vector (15 downto 0);
+      pwm_cnt  : in  std_logic_vector (15 downto 0);
+      pwm      : out std_logic);
+  end component omsp_pwm;
+
+  component counter is
+    generic (
+      WIDTH : integer;
+      MAX   : integer);
+    port (
+      clk   : in  std_logic;
+      reset : in  std_ulogic;
+      count : out std_logic_vector (WIDTH-1 downto 0));
+  end component counter;
+  
+  
 
   signal mclk : std_logic;
   signal puc : std_logic;
@@ -142,6 +171,9 @@ architecture rtl of openMSP430_uart is
   signal uart_dout : std_logic_vector (15 downto 0);
   signal uart_irq  : std_logic;
 
+  signal omsp_pwm_dout : std_logic_vector (15 downto 0);
+
+  signal pwm_cnt : std_logic_vector (15 downto 0);
 
 --------------------------------------------------------------------------------
 
@@ -246,10 +278,33 @@ begin
     txd         => TXD
   );
 
+  omsp_pwm_1 : omsp_pwm
+    generic map (
+      ADDR      => 16#0160#,
+      PWM_WIDTH => 16)
+    port map (
+      mclk     => mclk,
+      puc      => puc,
+      per_addr => per_addr,
+      per_en   => per_en,
+      per_wen  => per_wen,
+      per_din  => per_din,
+      per_dout => omsp_pwm_dout,
+      pwm_cnt  => pwm_cnt,
+      pwm      => PWM);
 
+  counter_1 : counter
+    generic map (
+      WIDTH => 16,
+      MAX   => 2**16 - 2)
+    port map (
+      clk   => mclk,
+      reset => puc,
+      count => pwm_cnt);
+  
 --------------------------------------------------------------------------------
 
-  per_dout <= uart_dout or omsp_quadcount_dout;
+  per_dout <= uart_dout or omsp_quadcount_dout or omsp_pwm_dout;
   
   irq <= (6 => uart_irq,
           7 => omsp_quadcount_irq,