Base Counter component (Verilog) example?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
JiSt_4468101
Level 1
Level 1
First reply posted First question asked First like given

I'm a relative noob to PSOC, and am trying to identify the simplest/best (leaning strongly toward simplest 🙂 approach to implementing a counter that can count up and down.  The 'Base Counter' verilog component outwardly looks like it might fit the bill (specifically, it's 'Clock and Direction' mode), but I can find no data sheet, documentation, code examples, etc for it.  (I've started picking my way through the .v file for it, but it's slow going for a noob.)

Is there any type of code example for the use of this component?  If someone more experienced thinks this is not the simplest/best approach to implementing a counter that can count up and/or down, I'd be open to suggestions!

I'm trying to implement a step/dir stepper driver, and would ideally like to use the counter value to keep track the motor's assumed position, as it is subsequently fed pos/neg steps by a PID process, if that helps add any clarity to what I'm trying to get to.  The other side of that is that I'd like it to sort of be a 'fire and forget' type of process - w/o the need for interrupts, continually calling the stepper routine, etc - so call a 'moveToPosition(p)' and/or 'moveSteps(s)' type of function, would set the counter's compare or period value, sets the direction needed to get there, and then the hardware drives the needed number of step pulses to get to the target position, w/o the firmware having to really be involved.  (I'm also open to suggestions on that type of process, if anyone has any to offer!)

Oh, I'm working with a PSOC62 on the CY8CKIT-062-WiFi-BT Pioneer Kit.

Thanks for any assistance - I'm loving the PSOC world, it's just a whole 'nuther level beyond the simpler uC's I've used in the past! 🙂

Jim

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Although I think that using Datapath should be more efficient, I tried using Verilog.

I used CY8CKIT-062-WiFi-BT.

========================

//`#start body` -- edit after this line, do not edit this line

module ud_cntr(

    input            rst,    /* cync clear */

    input            clk,    /* clock */

    input            up_ndn, /* 0: down 1: up */

    input      [7:0] max,    /* max value */

    output reg [7:0] cnt,    /* count value */

    output           tc      /* terminal count */

    ) ;

  

    assign tc = (up_ndn == 1'b1) ? cnt == max : cnt == 8'd0 ;

  

    always @(posedge clk) begin

        if (rst == 1'b1)

            if (up_ndn == 1'b1) /* up count */

                cnt <= 8'd0 ;

            else /* down count */

                cnt <= max ;

        else

            if (up_ndn == 1'b1) /* up count */

                if (cnt < max)

                    cnt <= cnt + 8'd1 ;

                else

                  cnt <= 8'd0 ;

            else /* down count */

               if (cnt > 8'd0)

                   cnt <= cnt - 8'd1 ;

               else

                   cnt <= max ;

    end

  

endmodule

//`#end` -- edit above this line, do not edit this line

========================

To test the module, I utilized tty_utils.[ch] and func_list.[ch] from my sample code

MCU Tester, a Swiss Army Knife for PSoC (CY8CKIT-062-BLE version)

Tera Term log

001-TeraTerm-log.JPG

Schematic

002-schematic.JPG

Pins

003-pins.JPG

main_cm4.c

==================

#include "project.h"

#include "stdio.h"

#include "tty_utils.h"

#include "func_list.h"

int current_core = USE_CM4 ;

void do_help(void) ;

void do_step(void) ;

void do_run(void) ;

void do_up(void) ;

void do_down(void) ;

void do_max(void) ;

void do_reset(void) ;

void do_status(void) ;

void cycle_clock(void) ;

void show_values(void) ;

f_list_type main_func_list[] = {

    { "help",   do_help,   "show help message"           },

    { "step",   do_step,   "advance 1 cycle"             },

    { "run",    do_run,    "advance n cycles:<ex> run 4" },

    { "up"  ,   do_up,     "set direction to up count"   },

    { "down",   do_down,   "set direction to down count" },

    { "max",    do_max,    "set max vaule"               },

    { "reset",  do_reset,  "reset the counter"           },

    { "status", do_status, "show current setup"          },

    { 0,       0,          0 }

} ;

void init_hardware(void)

{

    __enable_irq(); /* Enable global interrupts. */

   

    tty_init(USE_CM4) ;

}

int main(void)

{

    func_ptr func ;

   

    init_hardware() ;

  

    cls() ;

    splash("PSoC 6 Verilog Counter Test") ;

    do_help() ;

    prompt("> ") ;

    for(;;)

    {

        if (get_line()) {

            func = get_func(main_func_list, str) ;

            if (func) {

                func() ;

            } else {

                print("Unknown Command: ") ;

                print(str) ;

                print("\r\n") ;

                do_help() ;

            }  

            prompt("> ") ;

        }   

    }

}

void cycle_clock(void)

{

    uint8_t tmp ;

    tmp = Control_Reg_Read() ;

    tmp = tmp ^ 0x02 ; /* clock = 0 */

    Control_Reg_Write(tmp) ;

    tmp = tmp | 0x02 ; /* clock = 1 */

    Control_Reg_Write(tmp) ;

    tmp = tmp ^ 0x02 ; /* clock = 0 */  

    Control_Reg_Write(tmp) ;   

}

void show_values(void)

{

    char buf[32] ;

    snprintf(buf, 30, "%d %d\n\r", CNT_Read(), TC_Read()) ;

    print(buf) ;

}

void do_help(void)

{

    show_help(main_func_list) ;

}

void do_step(void)

{

    cycle_clock() ;

    show_values() ;

}

void do_run(void)

{

    int i, n ;

    sscanf(str, "%*s %d", &n) ;

    for (i = 0 ; i < n ; i++ ) {

        cycle_clock() ;

        show_values() ;

        CyDelay(10) ;

    }

}

void do_up(void)

{

    uint8_t tmp ;

    tmp = Control_Reg_Read() ;

    tmp |= 0x4 ; /* up_ndn = 1 */

    Control_Reg_Write(tmp) ;

}

void do_down(void)

{

    uint8_t tmp ;

    tmp = Control_Reg_Read() ;

    tmp ^= 0x4 ; /* up_ndn = 0 */

    Control_Reg_Write(tmp) ;

}

void do_max(void)

{

    int max ;

    sscanf(str, "%*s %d", &max) ;

    max_Write(max) ;

}

void do_reset(void)

{

    uint8_t tmp ;

    tmp = Control_Reg_Read() ;

    tmp |= 0x01 ; /* reset = 1 */

    Control_Reg_Write(tmp) ;

    cycle_clock() ;

    tmp ^= 0x01 ; /* reset = 0 */

    Control_Reg_Write(tmp) ;

   

    show_values() ;

}

void do_status(void)

{

    uint8_t tmp, max, cnt, tc ;

    tmp = Control_Reg_Read() ;

    max = max_Read() ;

    cnt = CNT_Read() ;

    tc = TC_Read() ;

    print("=== Current Status ===\n\r") ;

    snprintf(str, STR_BUF_LEN, "Reset: %d\n\r", tmp & 0x01) ;

    print(str) ;

    snprintf(str, STR_BUF_LEN, "Clock: %d\n\r", (tmp >> 1) & 0x01) ;

    print(str) ;

    print("Direction: ") ;

    if (tmp & 0x04) {

        print("Up\n\r") ;

    } else {

        print("Down\n\r") ;

    }

    snprintf(str, STR_BUF_LEN, "Max: %d\n\r", max) ;

    print(str) ;

    snprintf(str, STR_BUF_LEN, "Count: %d\n\r", cnt) ;

    print(str) ;

    snprintf(str, STR_BUF_LEN, "Terminal Count: %d\n\r", tc) ;

    print(str) ;

    print("\n\r") ; 

}

==================

moto

View solution in original post

0 Likes
3 Replies