Button to set or unset a value

Need some help on a project you are working on or got stuck on a tutorial? Post your questions here.
Post Reply
ellisgl
Posts: 14
Joined: December 24th, 2015, 9:43 pm

Button to set or unset a value

Post by ellisgl » January 28th, 2016, 3:54 pm

I wrote this code, but it seems that 'start' never gets set (so no automatic 1Hz clock). The simulation works fine. I'm using the debounce code from the blog.

Code: Select all

`timescale 1ns / 1ns
/**
 * External Input Handler
 * Deals with Addressing, Data, Steping, Running, Clearing, Clock Generation
 */
module inreg(
  input        extCLK,
  input  [3:0] extaddr,
  input  [7:0] extdata,
  input        extrun,
  input        extload,
  input        extauto,
  input        extstep,
  input        extclear,
  input        extstart,
  input        enio,
  input        nHLT,
  output [3:0] ABUS,
  output [7:0] WBUS,
  output       nWEram,
  output       CLR,
  output       nCLR,
  output       CLK,
  output       nCLK,
  output       run
);

  reg         creg  = 1'b0;
  reg  [24:0] ccnt  = 25'd0;
  reg         start = 1'b0;
  reg         sprev = 1'b0;
  
  wire        load;
  wire        step;
  wire        startc;
  wire        auto;

  debounce stepclean (extCLK, extstep,  step);
  debounce startclean(extCLK, extstart, startc);

  assign load                  = extload;
  assign CLR                   = extclear;

  // Assign our inverses
  assign nCLK                  = ~CLK;
  assign nCLR                  = ~CLR;

  // Assign the rest
  assign run                   = extrun;
  assign auto                  = extauto;
  assign {ABUS, WBUS, nWEram}  = (enio) ? {extaddr, extdata, ~load} : {4'bz, 8'bz, 1'bz};
  assign CLK                   = (run && !auto) ? step : (run && auto) ? creg : 1'b0;

  // Clock generator and stuff
  always @(posedge extCLK or posedge CLR)
    begin
      if(CLR)
        begin
          // CLEAR
          //$display("CLEAR FROM INREG");
          start <= 1'b0;
          sprev <= 1'b0;
          ccnt  <= 3'b0;
          creg  <= 1'b0;
        end
      else if(extCLK)
        begin
          if(!nHLT)
            begin
              creg <= 0;
            end
          if(run && auto)
            begin
              if(start)
                begin
                  // 1Hz Clock
                  if(ccnt == 25'd24999999)
                    begin
                      creg  <= ~creg;
                      ccnt <= 25'b0;
                    end
                  else
                    begin
                      ccnt <= ccnt + 1'd1;
                    end
                end
                
              if(startc)
                begin
                  // Stop the spamming of start
                  if(!sprev)
                    begin
                      sprev <= 1'b1;
                      start <= ~start;
                    end
                end
              else
                begin
                  if(sprev)
                    begin
                      sprev <= 1'b0;
                    end
                end
            end
        end
    end
endmodule

ellisgl
Posts: 14
Joined: December 24th, 2015, 9:43 pm

Re: Button to set or unset a value

Post by ellisgl » January 28th, 2016, 9:16 pm

Actually simulation shows that the CLK going high for one tick and right back down. Working on trying to the clock to 1/2 second on and 1/2 second off.. I lowered the ccnt to 24'd11 to make it easier (quicker) to test, and creg toggles hight when ccnt is 0, but when it's 1 - 11, it's low.

ellisgl
Posts: 14
Joined: December 24th, 2015, 9:43 pm

Re: Button to set or unset a value

Post by ellisgl » January 28th, 2016, 10:56 pm

Getting closer. The if statement for the creg and all that just doesn't play nice. Did a combined short if, and now the CLK looks good in simulation, but still doesn't run on the board.

Code: Select all

`timescale 1ns / 1ns
/**
 * External Input Handler
 * Deals with Addressing, Data, Steping, Running, Clearing, Clock Generation
 */
module inreg(
  input        extCLK,
  input  [3:0] extaddr,
  input  [7:0] extdata,
  input        extrun,
  input        extload,
  input        extauto,
  input        extstep,
  input        extclear,
  input        extstart,
  input        enio,
  input        nHLT,
  output [3:0] ABUS,
  output [7:0] WBUS,
  output       nWEram,
  output       CLR,
  output       nCLR,
  output       CLK,
  output       nCLK,
  output       run
);

  reg         creg  = 1'b0;
  reg  [24:0] ccnt  = 25'd0;
  reg         start = 1'b0;
  reg         sprev = 1'b0;
  
  wire        load;
  wire        step;
  wire        startc;
  wire        auto;

  debounce stepclean (extCLK, extstep,  step);
  debounce startclean(extCLK, extstart, startc);

  assign load                  = extload;
  assign CLR                   = extclear;

  // Assign our inverses
  assign nCLK                  = ~CLK;
  assign nCLR                  = ~CLR;

  // Assign the rest
  assign run                   = extrun;
  assign auto                  = extauto;
  assign {ABUS, WBUS, nWEram}  = (enio) ? {extaddr, extdata, ~load} : {4'bz, 8'bz, 1'bz};
  assign CLK                   = (run && !auto) ? step : (run && auto) ? creg : 1'b0;

  // Clock generator and stuff
  always @(posedge extCLK or posedge CLR)
    begin
      if(CLR)
        begin
          // CLEAR
          //$display("CLEAR FROM INREG");
          start <= 1'b0;
          sprev <= 1'b0;
          ccnt  <= 3'b0;
          creg  <= 1'b0;
        end
      else if(extCLK)
        begin
          if(!nHLT)
            begin
              creg <= 0;
            end
          if(run && auto)
            begin
              if(start)
                begin
                  // 1Hz Clock
                  {ccnt, creg} <= (ccnt == 25'd24999999) ? {25'd0, ~creg} : { ccnt + 1'b1, creg};
                end
                
              if(startc)
                begin
                  // Stop the spamming of start
                  if(!sprev)
                    begin
                      sprev <= 1'b1;
                      start <= ~start;
                    end
                end
              else
                begin
                  if(sprev)
                    begin
                      sprev <= 1'b0;
                    end
                end
            end
        end
    end
endmodule

ellisgl
Posts: 14
Joined: December 24th, 2015, 9:43 pm

Re: Button to set or unset a value

Post by ellisgl » January 29th, 2016, 12:17 pm

It works now. I changed extCLK to clk (thinking it might not have been getting the clock from board - not sure if that's true) and I changed a couple of things.

Code: Select all

    `timescale 1ns / 1ns
    /**
     * External Input Handler
     * Deals with Addressing, Data, Steping, Running, Clearing, Clock Generation
     */
    module inreg(
      input        clk,
      input  [3:0] extaddr,
      input  [7:0] extdata,
      input        extrun,
      input        extload,
      input        extauto,
      input        extstep,
      input        extclear,
      input        extstart,
      input        enio,
      input        nHLT,
      output [3:0] ABUS,
      output [7:0] WBUS,
      output       nWEram,
      output       CLR,
      output       nCLR,
      output       CLK,
      output       nCLK,
      output       run
    );

      reg         creg  = 1'b0;
      reg  [24:0] ccnt  = 25'd0;
      reg         start = 1'b0;
      reg         sprev = 1'b0;
      
      wire        load;
      wire        step;
      wire        startc;
      wire        auto;

      debounce stepclean (clk, extstep,  step);
      debounce startclean(clk, extstart, startc);

      assign load                  = extload;
      assign CLR                   = extclear;

      // Assign our inverses
      assign nCLK                  = ~CLK;
      assign nCLR                  = ~CLR;

      // Assign the rest
      assign run                   = extrun;
      assign auto                  = extauto;
      assign {ABUS, WBUS, nWEram}  = (enio) ? {extaddr, extdata, ~load} : {4'bz, 8'bz, 1'bz};
      assign CLK                   = (run && !auto) ? step : (run && auto) ? creg : 1'b0;

      // Clock generator and stuff
      always @(posedge clk or posedge CLR)
        begin
          if(CLR)
            begin
              // CLEAR
              start <= 1'b0;
              sprev <= 1'b0;
              ccnt  <= 3'b0;
              creg  <= 1'b0;
            end
          else
            begin
              if(!nHLT)
                begin
                  creg <= 0;
                end
              if(run && auto)
                begin
                  if(start)
                    begin
                      // 1Hz Clock
                      {ccnt, creg} <= (ccnt == 25'd24_999_999) ? {25'd0, ~creg} : { ccnt + 1'b1, creg};
                    end
                  if(startc)
                    begin
                      // Stop the spamming of start
                      if(!sprev)
                        begin
                          sprev <= 1'b1;
                          start <= ~start;
                        end
                    end
                  else
                    begin
                      if(sprev)
                        begin
                          sprev <= 1'b0;
                        end
                    end
                end
            end
        end
    endmodule
    

embmicro
Site Admin
Posts: 834
Joined: March 24th, 2013, 12:45 pm

Re: Button to set or unset a value

Post by embmicro » February 1st, 2016, 5:00 pm

If you changed the clock name but didn't change the UCF file to tell it what pin the new name should connect to, it won't work. If you don't constrain your IO, the Xilinx tools just make stuff up and pick random pins.

Post Reply