aboutsummaryrefslogtreecommitdiff
path: root/docs/j1eforth/fpga/src/utils.vhd
blob: 19eb1f7ab1a8fc9627aea860148cb042feb54d8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
-------------------------------------------------------------------------------
-- Title      : UART
-- Project    : UART
-------------------------------------------------------------------------------
-- File        : utils.vhd
-- Author      : Philippe CARTON 
--               (philippe.carton2@libertysurf.fr)
-- Organization:
-- Created     : 15/12/2001
-- Last update : 8/1/2003
-- Platform    : Foundation 3.1i
-- Simulators  : ModelSim 5.5b
-- Synthesizers: Xilinx Synthesis
-- Targets     : Xilinx Spartan
-- Dependency  : IEEE std_logic_1164
-------------------------------------------------------------------------------
-- Description: VHDL utility file
-------------------------------------------------------------------------------
-- Copyright (c) notice
--    This core adheres to the GNU public license 
--
-------------------------------------------------------------------------------
-- Revisions       :
-- Revision Number :
-- Version         :
-- Date    :
-- Modifier        : name <email>
-- Description     :
--
------------------------------------------------------------------------------


-------------------------------------------------------------------------------
-- Revision list
-- Version   Author                 Date                        Changes
--
-- 1.0      Philippe CARTON  19 December 2001                   New model
--	    philippe.carton2@libertysurf.fr
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------- 
-- Synchroniser: 
--    Synchronize an input signal (C1) with an input clock (C).
--    The result is the O signal which is synchronous of C, and persist for
--    one C clock period.
-------------------------------------------------------------------------------- 
library IEEE,STD;
use IEEE.std_logic_1164.all;

entity synchroniser is
   port (
      C1 : in std_logic;-- Asynchronous signal
      C :  in std_logic;-- Clock
      O :  out std_logic);-- Synchronised signal
end synchroniser;

architecture Behaviour of synchroniser is
   signal C1A : std_logic;
   signal C1S : std_logic;
   signal R : std_logic;
begin
   RiseC1A : process(C1,R)
   begin
      if Rising_Edge(C1) then
         C1A <= '1';
      end if;
      if (R = '1') then
         C1A <= '0';
      end if;
   end process;

   SyncP : process(C,R)
   begin
      if Rising_Edge(C) then
         if (C1A = '1') then
            C1S <= '1';
         else C1S <= '0';
         end if;
         if (C1S = '1') then
            R <= '1';
         else R <= '0';
         end if;
      end if;
      if (R = '1') then
         C1S <= '0';
      end if;
   end process;
   O <= C1S;
end Behaviour;

-------------------------------------------------------------------------------
-- Counter
--    This counter is a parametrizable clock divider.
--    The count value is the generic parameter Count.
--    It is CE enabled. (it will count only if CE is high).
--    When it overflow, it will emit a pulse on O. 
--    It can be reseted to 0. 
-------------------------------------------------------------------------------
library IEEE,STD;
use IEEE.std_logic_1164.all;

entity Counter is
  generic(Count: INTEGER range 0 to 65535); -- Count revolution
  port (
     Clk      : in  std_logic;  -- Clock
     Reset    : in  std_logic;  -- Reset input
     CE       : in  std_logic;  -- Chip Enable
     O        : out std_logic); -- Output
end Counter;

architecture Behaviour of Counter is
begin
  counter : process(Clk,Reset)
     variable Cnt : INTEGER range 0 to Count-1;
  begin
     if Reset = '1' then
        Cnt := Count - 1;
        O <= '0';
     elsif Rising_Edge(Clk) then
        if CE = '1' then
           if Cnt = 0 then
              O <= '1';
              Cnt := Count - 1;
           else
              O <= '0';
              Cnt := Cnt - 1;
           end if;
        else O <= '0';
        end if;
     end if;
  end process;
end Behaviour;