• 0
gwideman

Source for Cmod A7 Stopwatch demo?

Question

I'm wondering where do we find the source for the Cmod A7 Stopwatch demo? One the demo's page (https://reference.digilentinc.com/cmod_a7/cmod_a7/cmod_a7_stopwatch/start) I can only find links for the bit and bin files. Since this is the only one of the Cmod A7 demos that exercises the pins (as opposed to on-board features), it would be useful to have a known-good demo project to modify. Thanks!

Edited by gwideman

Share this post


Link to post
Share on other sites

10 answers to this question

Recommended Posts

  • 1

Hi @gwideman,

Here is a project (hdl and .xdc file attached) for the Cmod A7 that uses the external pins, with 8 pins (pins 1 through 8) showing the output of an 8-bit counter with pin 9 as the enable pin that needs to be provided a logic high signal for the counter to operate.

Let me know if you have any questions.

Thanks,
JColvin

CmodA7_Master.xdc

top.v

Share this post


Link to post
Share on other sites
  • 1

@gwideman,

... and here's the code I used within my Basys board to create a 1) clock, 2) timer, 3) stop watch, and 4) alarm.  It is component code, though.  You'll still need to make some connections to get it to work.  While I still use the clock today, I've switched mostly to either the rtclight version or the GPS clocked version, and neither of those have any external outputs.

Dan

Share this post


Link to post
Share on other sites
  • 0

Hi @gwideman,

I have not found the source code for the stop clock project as of yet. I do know that some classes use this type of project in their digital design classes. This might have been why we chose not to post the source code. I do know that the xadc project here uses the I/O pins.

cheers,

Jon

Share this post


Link to post
Share on other sites
  • 0
3 hours ago, jpeyron said:

Hi @gwideman,

I have not found the source code for the stop clock project as of yet. I do know that some classes use this type of project in their digital design classes. This might have been why we chose not to post the source code. I do know that the xadc project here uses the I/O pins.

cheers,

Jon

Thanks for your response, but ... that's pretty disappointing. Having, before purchase, taken note of the fact that demos were available, I thought they would actually contain code showing known good examples, so we would be off-to-the-races with hardware we could exercise, and revise to use other I/Os. As a non-student customer, withholding that code subtracts value from the product -- it's just a time-wasting obstacle.

As for the xadc project, it only exercises inputs, and at that analog inputs. These are not of interest at the moment. In fact it was only belatedly that I discovered that these I/Os are not direct to the FPGA, and can't be used as GPIOs (unless you remove the intervening voltage divider/filter components).

Of course my complaint here is not fatal, I can probably work out what's needed from the example that runs the on-board LEDs, and examples from elsewhere for other boards. It just seems dumb that a product that in other respects is so ready to plug into a breadboard and play actually lacks examples to do so.

Share this post


Link to post
Share on other sites
  • 0
13 hours ago, JColvin said:

Here is a project (hdl and .xdc file attached) for the Cmod A7 that uses the external pins, with 8 pins (pins 1 through 8) showing the output of an 8-bit counter with pin 9 as the enable pin that needs to be provided a logic high signal for the counter to operate.

Let me know if you have any questions.

Thanks, JColvin

 

Hi JColvin -- thanks for that project, it was helpful getting started.  Especially after I realized that pin 1 is at the Pmod end, not the USB end  :-).

Couple of followups -- I think there might be an issue in the xdc file:

set_property ... [get_ports clk]
create_clock ... [get_ports sysclk]

... I think the two clock names should match. At least, Vivado gave me a warning until I changed the second one to 'clk'.

Now, a question: I get warnings for all the I/Os as follows:

[DRC RPBF-3] IO port buffering is incomplete: Device port pio[1] expects both input and output buffering but the buffers are incomplete.

... and same for all the other pios. Any idea what this error message is all about? I guess it's complaining that the I/O pins have INOUT capability, but this design only uses them in one direction?    Google isn't coughing up anything very helpful for me.

Thanks!  Graham

 

 

Share this post


Link to post
Share on other sites
  • 0

@gwideman,

No, I think you've got it.  Vivado is trying to map your design to one that uses a tri-state I/O buffer.  Such a buffer has, for each pin, a control (drive output, or leave at high impedence), an input pin and an output pin.  By not specifying all three parts, you are leaving the buffer "incomplete".

Just a little bit of logic, such as:

port = (choice) ? 1'bz : output_value;

might be sufficient to get past the error.

Dan

Share this post


Link to post
Share on other sites
  • 0
7 hours ago, D@n said:

@gwideman,

 By not specifying all three parts, you are leaving the buffer "incomplete". Just a little bit of logic, such as:

port = (choice) ? 1'bz : output_value;

might be sufficient to get past the error.

Dan

@D@n

Thanks for the advice, yes I realize that the inout IOs really consist of an output, its tristate control, and its input. What I don't understand is how to explicitly or implicitly tell Vivado/Verilog how to configure that.  I have modified @JColvin 's example with what I think you're suggesting (see below), but I'm still getting RPBF-3 DRC warnings on all of pio[9..1] (the 8-bit counter.output, and the 1 bit enable input.)  Any further ideas? Thanks.

module top (clk, pio);
    input clk;
    inout [9:1] pio;
    
    reg [31:0] counter_0 = 0; // count clock cycles
    reg [ 7:0] counter_1 = 0; // count seconds
    wire [7:0] counter_1_in;
    
    wire en; // enable the counters when asserted
    
    localparam CLOCK_FREQUENCY = 12000000; // in hertz
    
    assign pio[8:1] = 1'b1 ? counter_1: 8'bz ;  // output counter #1 on GPIO 1-8
    assign counter_1_in = pio[8:1];
    
    assign en       = pio[9];  // take enable as input from GPIO 9
    assign pio[9]   = 1'bz  ;    
    
    always@(posedge clk) 
    begin
        if (en == 1'b1)   //if GPIO 9 is set logic high 
        begin       
            if (counter_0 == CLOCK_FREQUENCY-1)
                counter_0 <= 0;       //reset counter after F-1
            else
                counter_0 <= counter_0 + 1; //inc counter
        end 

        if (en == 1'b1 && counter_0 == CLOCK_FREQUENCY-1)   // once-per-sec...
            counter_1 <= counter_1 + 1;                     // inc secs counter
        else
            counter_1 <= counter_1;
    end
endmodule

 

Share this post


Link to post
Share on other sites
  • 0

@gwideman,

Let me offer two thoughts, based on experience and not the text book

  1. When I've done this with a bus of more than one element, I've always specified the 'z' value for every element.  In your case, that would become 8'hzzzz_zzzz.
  2. If you aren't going to use this I/O in a bidirectional fashion ... why not just declare it as output ports instead of inout ports?
  3. Ok, I'll offer a third thought as well--this one from the textbook I don't like using: There is also a non-portable solution that Xilinx provides.  This would be to directly instantiate one (or 8-9 in your case) of their IOBUF primitives.  See the Libraries User Guide for more details.

Please write back and let us know which option you choose, or if you want to keep looking for a solution,

Dan

Share this post


Link to post
Share on other sites
  • 0

Hi @D@n, thanks again for your comments. I now have a sample which avoids warning messages (mostly, see below). I show it below for others who may stumble in here with the same questions.

The key element for avoiding the RPBF-3 DRC warnings (as D@n) said) is to treat the I/Os either as unidirectional inputs or outputs (and let Vivado sort out the appropriate configuration) or to treat them explicitly as a tristate output driver plus an input buffer, using the IOBUF primitive.

Below are an xdc file and module that use the former strategy.

## xdc file for demo_counter 

# Clock signal 12 MHz
set_property -dict {PACKAGE_PIN L17 IOSTANDARD LVCMOS33} [get_ports clk]
create_clock -period 83.330 -name sys_clk_pin -waveform {0.000 41.660} -add [get_ports clk]

## GPIO Pins (uncomment rows in the Digilent-provide xdc file) 
set_property -dict {PACKAGE_PIN M3 IOSTANDARD LVCMOS33} [get_ports {pio[1]}]
[... etc to pio[8] ]

# Rename ports that need to be treated differently in module arg list
set_property -dict {PACKAGE_PIN A14 IOSTANDARD LVCMOS33} [get_ports enpio]
# set_property -dict {PACKAGE_PIN A14 IOSTANDARD LVCMOS33} [get_ports {pio[9]}]

##-------- Set using Vivado I/O Ports panel --------
set_property DRIVE 4 [get_ports {pio[1]}]
[... etc to pio[8] ]

set_property SLEW SLOW [get_ports {pio[1]}]
[... etc to pio[8] ]

set_property PULLUP true [get_ports enpio]

##------- Set using Vivado  Tools > Edit Device Properties -------
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property CFGBVS VCCO [current_design]

.

module top (clk, pio, enpio);
    input clk;
    output [8:1] pio;
    input enpio;
    
    reg [31:0] counter_0 = 0; // count clock cycles
    reg [ 7:0] counter_1 = 0; // counter for output pins
    
    localparam  MASTER_CLOCK_F     = 12000000; // in hertz
    localparam  COUNT_PER_SEC      =  10;   
    localparam  MASTER_CYCLES_PER_COUNT = MASTER_CLOCK_F / COUNT_PER_SEC;
    
    assign pio[8:1]     = counter_1 ; 
    
    always@(posedge clk) 
    begin
        if (enpio == 1'b1)   
        begin       
            if (counter_0 == MASTER_CYCLES_PER_COUNT-1)
                counter_0 <= 0;       
            else
                counter_0 <= counter_0 + 1; 
        end 

        if (enpio == 1'b1 && counter_0 == MASTER_CYCLES_PER_COUNT-1)
            counter_1 <= counter_1 + 1;                     
    end
endmodule

The main point to note (with regard to avoiding RPBF-3 warnings) is that in the xdc file, the port(s) used as outputs are given a name separate from the port(s) used as inputs.  This allows them to be listed and named separately in the module top (xxx) argument list, so that those arguments can separately be given attributes of either input or output.

With that done, it seems there' s no need to make any other accommodations (such as the earlier-suggested assigning z to outputs or inputs).

This design still produces a couple of warnings:

-- "debug core was not detected" (Fair enough, I guess.)

-- [Synth 8-6014] Unused sequential element counter_1_reg was removed. This one appears to be a Vivado bug: https://forums.xilinx.com/t5/Synthesis/Many-spurious-quot-Synth-8-6014-Unused-sequential-element-was/td-p/769636

OK, I hope that helps others who want a clean starting point for exercising the Cmod A7 with Verilog and Vivado.  -- Graham

 

 

 

Edited by gwideman
Removed superfluous counter_1_in

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now