|
''' |
|
Created on 22 Oct 2016 |
|
|
|
@author: Josy |
|
|
|
# Copyright (c) 2016 Josy Boelen |
|
# |
|
# This program is free software: you can redistribute it and/or modify |
|
# it under the terms of the GNU General Public License as published by |
|
# the Free Software Foundation, either version 3 of the License, or |
|
# (at your option) any later version. |
|
# |
|
# This program is distributed in the hope that it will be useful, |
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
# GNU General Public License for more details. |
|
# |
|
# You should have received a copy of the GNU General Public License |
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
''' |
|
|
|
from myhdl import Signal, intbv, ResetSignal, always_seq, always_comb, instances, toVHDL |
|
|
|
from Utilities import hdlutils |
|
|
|
|
|
class BasicUpCounter(object): |
|
''' a basic up-counter ''' |
|
def __init__(self, LEN_COUNT, Clk, Reset, SClr=None, CntEn=None, Q=None): |
|
''' |
|
LEN_COUNT: == MAX_COUNT + 1 |
|
''' |
|
self._maxcount = LEN_COUNT - 1 |
|
self.clk = Clk |
|
self.reset = Reset |
|
self.sclr = SClr if SClr is not None else False |
|
self.bccnten = CntEn if CntEn is not None else True |
|
self.Q = Q if Q is not None else Signal(intbv(0)[hdlutils.widthu(LEN_COUNT):]) |
|
|
|
def rtl(self): |
|
''' the counter ''' |
|
@always_seq(self.clk.posedge, self.reset) |
|
def synch(): |
|
''' counting ... ''' |
|
if self.bccnten or self.sclr: |
|
if self.sclr: |
|
self.Q.next = 0 |
|
else: |
|
if self.Q < self._maxcount: |
|
self.Q.next = self.Q + 1 |
|
else: |
|
self.Q.next = 0 |
|
|
|
return synch |
|
|
|
class UpCounter(BasicUpCounter): |
|
''' a counter with some extras ''' |
|
def __init__(self, LEN_COUNT, Clk, Reset, SClr=None, CntEn=None, Q=None, |
|
IsZero=None): |
|
# must call base class first |
|
super(UpCounter, self).__init__(LEN_COUNT, Clk, Reset, SClr, CntEn, Q) |
|
self.IsZero = IsZero if IsZero is not None else Signal(bool()) |
|
|
|
def rtl(self): |
|
''' augmenting the basic counter ''' |
|
# first instantiate the rtl of the basic counter |
|
bcrtl = super(UpCounter, self).rtl() |
|
|
|
if self.IsZero != 'Open': |
|
@always_comb |
|
def aiz(): |
|
''' isZero? ''' |
|
if self.Q == 0: |
|
self.IsZero.next = 1 |
|
else: |
|
self.IsZero.next = 0 |
|
|
|
return instances() |
|
|
|
|
|
class OneShotCounter(UpCounter): |
|
''' making the UpCounter stop at a given maximum ''' |
|
def __init__(self, LEN_COUNT, Clk, Reset, MaxCount, SClr=None, CntEn=None, Q=None, |
|
IsZero=None): |
|
super(OneShotCounter, self).__init__(LEN_COUNT, Clk, Reset, SClr, None, Q, IsZero=IsZero) |
|
# make sure that _cnten is now a signal (under our control) |
|
self.osccnten = CntEn if CntEn is not None else True |
|
self.bccnten = Signal(bool(0)) |
|
self.maxcount = MaxCount |
|
|
|
def rtl(self): |
|
# first instantiate the rtl of the up-counter |
|
uc = super(OneShotCounter, self).rtl() |
|
|
|
@always_comb |
|
def osc(): |
|
''' making it a one-shot-counter ''' |
|
self.bccnten.next = 0 |
|
if self.Q < self.maxcount: |
|
self.bccnten.next = self.osccnten |
|
|
|
return instances() |
|
|
|
|
|
if __name__ == '__main__': |
|
def top_oo(LEN_COUNT, Clk, Reset, MaxCount, SClr, CntEn, Q, IsZero): |
|
return OneShotCounter(LEN_COUNT, Clk, Reset, MaxCount, SClr=SClr, CntEn=CntEn, Q=Q, IsZero=IsZero).rtl() |
|
|
|
def convert(): |
|
C_LEN_COUNT = 256 |
|
Clk = Signal(bool(0)) |
|
Reset = ResetSignal(0, 1, True) |
|
SClr = Signal(bool(0)) |
|
CntEn = Signal(bool(0)) |
|
Q = Signal(intbv(0)[hdlutils.widthu(C_LEN_COUNT):]) |
|
MaxCount = Signal(intbv(0)[hdlutils.widthu(C_LEN_COUNT):]) |
|
IsZero = Signal(bool(0)) |
|
|
|
toVHDL.no_initial_values = True |
|
toVHDL.std_logic_ports = True |
|
toVHDL( top_oo, C_LEN_COUNT, Clk, Reset, MaxCount, SClr, CntEn, Q, IsZero) |
|
|
|
|
|
convert() |