0
\$\begingroup\$

I am trying to implement a 8-bit counter that does both BCD(Binary Code decimal) and gray code sequence. If the input control = 0, the circuit will count in BCD and if the input control = 1, the circuit will count in gray code sequence. Here is my implementation:

module grayBCDcounter(
    input clk, control,
    output reg [2:0] y1,
);

reg [2:0] state          // there will be 8 states: 1st state :000
                         // 2nd state: 001, 3rd state: 010 and so on
                         // my last state will be 111

parameter s0=3'b000, s1=3'b001, s2=3'b010, s3=3'b011,
                s4=3'b100, s5=3'b101, s6=3'b110, s7=3'b111;

always @ (posedge clk)
begin
case(state)
s0: state <= s0;
s1: state <= s1;
s2: if (control == 0)
       begin
          state <= s2;
       end
    else if(control ==1)
       begin
          state <= s3;
       end    
s3: // and so on
endcase
end

always @ (posedge clk)
   begin

   if (state == s0)
     begin
        y1 <= 0;
     end
   else if(state == s1)
     begin
        y1 <= 1;
     end
   else if // so on
   end
   end

endmodule

When control variable is 0, I want to execute s0,s1,s2,s3,s4,s5, and so on as you can see(BCD), and when control variable is 1, I want to execute s0,s1,s3,s2,s6,s7,s5,s4 respectively (gray code)

When I run a test cases on it, it somehow only prints s0 and seems to be constant throughout the execution. My guess is that the state never goes off from s0.

Any tips on how I should implement the codes?

\$\endgroup\$
8
  • 2
    \$\begingroup\$ s0: state <= s0. "If in state 0, go to state 0". Why do you expect it to leave state 0? \$\endgroup\$ – Tom Carpenter May 11 '16 at 2:35
  • 1
    \$\begingroup\$ My advice to you is to draw out your state machine on paper and plan how it is going to transition. \$\endgroup\$ – Tom Carpenter May 11 '16 at 2:36
  • 1
    \$\begingroup\$ See my second comment. Work out how each state needs to transition to the next. \$\endgroup\$ – Tom Carpenter May 11 '16 at 2:59
  • 2
    \$\begingroup\$ As it is written, your state machine cannot ever leave state s0, because you haven't described in the code how it leaves s0. \$\endgroup\$ – Tom Carpenter May 11 '16 at 3:01
  • 1
    \$\begingroup\$ It is not 8 bit \$\endgroup\$ – Prakash Darji May 11 '16 at 5:59
1
\$\begingroup\$

I think you don't use FSM, instead make simple code like bellow,

module grayBCDcounter(
  input clk, rst_n, control,
  output wire [2:0] y1 
);

reg  [2:0] bcd_cnt, gray_cnt, cnt;

always @ (posedge clk or negedge rst_n)
begin
  if (!rst_n) begin
    bcd_cnt  <= 3'b0;
    cnt      <= 3'b0;
    gray_cnt <= 3'b0;
  end else begin
    bcd_cnt  <= (bcd_cnt + 1'd1) & {3{control}};
    cnt      <= (cnt + 1'd1) & {3{!control}};
    gray_cnt <= cnt ^ (cnt >> 1);
  end
end

assign y1 = control ? bcd_cnt : gray_cnt;

endmodule

Try it.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ If the gray code is intended to protect clock domain crossings (clearly not in this context, but more generally its likely) then the output select needs to be before the flops. \$\endgroup\$ – Sean Houlihane May 11 '16 at 10:58
  • \$\begingroup\$ I think its nothing to do with CDC. \$\endgroup\$ – Prakash Darji May 11 '16 at 15:41
  • 1
    \$\begingroup\$ Agreed, but when in practice will people be looking for information about gray coded counters? Lab exercises excepted. \$\endgroup\$ – Sean Houlihane May 12 '16 at 21:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.