OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [VHDL/] [threshold_comp.vhd] - Blame information for rev 330

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 323 jshamlet
-- Copyright (c)2022 Jeremy Seth Henry
2
-- All rights reserved.
3
--
4
-- Redistribution and use in source and binary forms, with or without
5
-- modification, are permitted provided that the following conditions are met:
6
--     * Redistributions of source code must retain the above copyright
7
--       notice, this list of conditions and the following disclaimer.
8
--     * Redistributions in binary form must reproduce the above copyright
9
--       notice, this list of conditions and the following disclaimer in the
10
--       documentation and/or other materials provided with the distribution,
11
--       where applicable (as part of a user interface, debugging port, etc.)
12
--
13
-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
14
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
17
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
--
24
-- VHDL Units :  threshold_comp
25
-- Description:  Compares the value on Port_A to either Port_B or a fixed,
26
--            :   unsigned constant with hysteresis.
27
--
28
-- Revision History
29
-- Author          Date     Change
30
------------------ -------- ---------------------------------------------------
31
-- Seth Henry      06/29/22 Initial import
32
 
33
library ieee;
34
use ieee.std_logic_1164.all;
35
use ieee.std_logic_unsigned.all;
36
use ieee.std_logic_arith.all;
37
 
38
entity threshold_comp is
39
generic(
40
  Constant_B            : boolean := TRUE;
41
  Hysteresis            : integer := 2;
42
  Threshold             : integer := 0;
43
  Bus_Width             : integer := 16;
44
  Reset_Level           : std_logic := '1'
45
);
46
port(
47
  Clock                 : in  std_logic;
48
  Reset                 : in  std_logic;
49
  --
50
  Port_A_Data           : in  std_logic_vector(Bus_Width - 1 downto 0);
51
  Port_A_Update         : in  std_logic;
52
  Port_B_Data           : in  std_logic_vector(Bus_Width - 1 downto 0) := (others => '0');
53
  Port_B_Update         : in  std_logic := '0';
54
  --
55
  A_GT_B                : out std_logic;
56
  A_LTE_B               : out std_logic
57
);
58
end entity;
59
 
60
architecture behave of threshold_comp is
61
 
62
  function limit_int (x : in integer; y : in integer ) return integer is
63
    variable upper      : integer;
64
    variable retval     : integer;
65
  begin
66
    upper               := (2**y) - 1;
67
 
68
    if( x <= 0 )then
69
      retval            := 0;
70
    elsif( x > upper )then
71
      retval            := upper;
72
    else
73
      retval            := x;
74
    end if;
75
    return retval;
76
  end function;
77
 
78
  constant Int_Width    : integer := Bus_Width + 1;
79
 
80
  constant Comp_Val_r_i : integer := Threshold + Hysteresis;
81
  constant Comp_Val_r_l : integer := limit_int(Comp_Val_r_i, Int_Width);
82
  constant Comp_Val_r   : std_logic_vector(Bus_Width downto 0) :=
83
                            conv_std_logic_vector(Comp_Val_r_l, Int_Width);
84
 
85
  constant Comp_Val_f_i : integer := Threshold - Hysteresis;
86
  constant Comp_Val_f_l : integer := limit_int(Comp_Val_f_i, Int_Width);
87
  constant Comp_Val_f   : std_logic_vector(Bus_Width downto 0) :=
88
                            conv_std_logic_vector(Comp_Val_f_l, Int_Width);
89
 
90
  signal Hist_Dir       : std_logic := '0';
91
  signal Update_q       : std_logic := '0';
92
  signal Update_qq      : std_logic := '0';
93
 
94
  signal Port_A_q       : std_logic_vector(Bus_Width downto 0) :=
95
                            (others => '0');
96
 
97
  signal Port_B_r       : std_logic_vector(Bus_Width downto 0) :=
98
                            (others => '0');
99
 
100
  signal Port_B_f       : std_logic_vector(Bus_Width downto 0) :=
101
                            (others => '0');
102
 
103
  signal Port_A_LT_B    : std_logic := '0';
104
 
105
begin
106
 
107
Constant_Port_B : if( Constant_B )generate
108
 
109
  Compare_proc: process( Clock, Reset )
110
  begin
111
    if( Reset = Reset_Level )then
112
      Update_q          <= '0';
113
      Hist_Dir          <= '1';
114
      Port_A_q          <= (others => '0');
115
      A_GT_B            <= '0';
116
      A_LTE_B           <= '1';
117
    elsif( rising_edge(Clock) )then
118
 
119
      -- Update the internal registers on Update, then start a short shift
120
      --  register to pipeline the logic.
121
      Update_q          <= Port_A_Update;
122
      if( Port_A_Update = '1' )then
123
        Port_A_q        <= '0' & Port_A_Data;
124
      end if;
125
 
126
      -- Update the output on q
127
      if( Update_q = '1' )then
128
        if( Hist_Dir = '1' and Port_A_q >= Comp_Val_r )then
129
          Hist_Dir      <= '0';
130
          A_GT_B        <= '1';
131
          A_LTE_B       <= '0';
132
        end if;
133
        if( Hist_Dir = '0' and Port_A_q <= Comp_Val_f )then
134
          Hist_Dir      <= '1';
135
          A_GT_B        <= '0';
136
          A_LTE_B       <= '1';
137
        end if;
138
      end if;
139
 
140
    end if;
141
  end process;
142
 
143
end generate;
144
 
145
Variable_Port_B : if( not Constant_B )generate
146
 
147
  Compare_proc: process( Clock, Reset )
148
  begin
149
    if( Reset = Reset_Level )then
150
      Update_q          <= '0';
151
      Update_qq         <= '0';
152
      Hist_Dir          <= '1';
153
      Port_A_q          <= (others => '0');
154
      Port_B_r          <= (others => '0');
155
      Port_B_f          <= (others => '0');
156
      A_GT_B            <= '0';
157
      A_LTE_B           <= '1';
158
    elsif( rising_edge(Clock) )then
159
 
160
      -- Update the internal registers on Update, then start a short shift
161
      --  register to pipeline the logic.
162
      Update_q          <= Port_A_Update or Port_B_Update;
163
 
164
      if( Port_A_Update = '1' )then
165
        Port_A_q        <= '0' & Port_A_Data;
166
      end if;
167
 
168
      if( Port_B_Update = '1' )then
169
        Port_B_r        <= ('0' & Port_B_Data) + Hysteresis;
170
        Port_B_f        <= ('0' & Port_B_Data) - Hysteresis;
171
      end if;
172
 
173
      -- Clip the upper and lower thresholds so that the comparator can't get
174
      --  stuck and will trip on equal.
175
      Update_qq          <= Update_q;
176
 
177
      if( Port_B_R(Bus_Width) = '1' )then
178
        Port_B_R(Bus_Width) <= '0';
179
        Port_B_R(Bus_Width - 1 downto 0) <= (others => '1');
180
      end if;
181
 
182
      if( Port_B_F(Bus_Width) = '1' )then
183
        Port_B_F        <= (others => '0');
184
      end if;
185
 
186
      -- Update the output on qq to give the clipping logic a chance to update
187
      if( Update_qq = '1' )then
188
        if( Hist_Dir = '1' and Port_A_q >= Port_B_r )then
189
          Hist_Dir      <= '0';
190
          A_GT_B        <= '1';
191
          A_LTE_B       <= '0';
192
        end if;
193
        if( Hist_Dir = '0' and Port_A_q <= Port_B_f )then
194
          Hist_Dir      <= '1';
195
          A_GT_B        <= '0';
196
          A_LTE_B       <= '1';
197
        end if;
198
      end if;
199
 
200
    end if;
201
  end process;
202
 
203
end generate;
204
 
205
end architecture;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.