Added 2 new entities: counter and omsp_pwm.
Instances of these are inserted in the top-level.
--- /dev/null
+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;
+
--- /dev/null
+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;
+
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
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
+
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;
);
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;
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);
--------------------------------------------------------------------------------
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,