Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Writing a VHDL counter design help

Status
Not open for further replies.

TERRYWU3

Member level 1
Joined
Jan 10, 2003
Messages
40
Helped
1
Reputation
2
Reaction score
0
Trophy points
1,286
Activity points
301
Dear experts,

I want to design a counter which will depend on a input 8 bit bus .

if bus is "10011010" , my counter sequence is 1 ->3->4->7 ->1->3->4->7 loop .

if bus is "10000001" , counter sequence is 0->7->0->7 ... loop

My bus is random changed .

Would you please give me a advise or a reference information ??


Very very thanks again !
 

hi

Is this value 10011010 is input at start of counter......tell me clearly
 

Hi,

Here is the code :

signal counter, next_counter : integer range 0 to 7;

process(clk,reset)
begin
if(reset = '0') then
counter <= 1;
elsif(clk'event and clk='1') then
counter <= next_counter;
end if;
end process;

process(counter,bus)
begin
if(bus = "10011010")
if(counter = 1) then
next_counter <= 3;
elsif(counter = 3) then
next_counter <= 4;
elsif(counter = 4) then
next_counter <= 7;
else
next_counter <= 1;
end if;
end if;
end process;


If this is not what you want, plz free to post u r problem in detail

Check out for the syntax, i haven't compiled the code.

Regards,
dcreddy
 

nandhika said:
hi

Is this value 10011010 is input at start of counter......tell me clearly

sorry my describe unclearly.
the start value of counter depend on the first bit '1' of the bus.

if first bit 1 at bit 3 , then start counter value is 3
if next bit 1 at bit 6 , then second counter value is 6 ..... continue loop


very very thanks ~
 

Actually, what you describe is a sequencer, not a counter, where the sequence is determined by the input vector. Below you will find some code that might help you to do what you need. You can also try to add another state, so that if input = "00000000", the FSM goes to an invalid state. Check the syntax, since I don't have an available compiler in my PC at this moment.
You will need to complete code for state 12,3,4,5,6 and 7.

library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity count_at_input is
port(
clk : in std_logic; --Clock
rst : in std_logic; --asynchronous reset
seq : in std_logic_vector(7 downto 0); --sequence
Q : out std_logic_vector(2 downto 0) --output (count)
);
end count_at_input;



architecture counter of count_at_input is
signal Qp, Qn : std_logic_vector(2 downto 0); --Present and Next state
begin
combinational : process(seq,Qp)
begin
case Qp is
when "000" => --If reached, Bit 0 is 1
if(seq(1) = '1') then --If bit1=1, then next count = 1
Qn <= "001";
elsif(seq(2)='1') then --else if bit2=1, then next count =2
Qn<="010";
elsif(seq(3)='1') then --else if bit3=1, next count =3
Qn<="011";
elsif(seq(4)='1') then --else if bit4=1, next count=4
Qn<="100";
elsif(seq(5)='1') then --else if bit5=1, next count =5
Qn<="101";
elsif(seq(6)='1') then --else if bit6=1, next count =6
Qn<="110";
elsif(seq(7)='1') then --else if bit7=1, next count =7
Qn<="111";
else --if all other bits are 0, stay here
Qn<="000"; --or it could be Qn<=Qp;
end if;

when "001" => --If reached, bit 1=1
if(seq(2)='1') then --else if bit2=1, then next count =2
Qn<="010";
elsif(seq(3)='1') then --else if bit3=1, next count =3
Qn<="011";
elsif(seq(4)='1') then --else if bit4=1, next count=4
Qn<="100";
elsif(seq(5)='1') then --else if bit5=1, next count =5
Qn<="101";
elsif(seq(6)='1') then --else if bit6=1, next count =6
Qn<="110";
elsif(seq(7)='1') then --else if bit7=1, next count =7
Qn<="111";
if(seq(0) = '1') then --If bit0=1, then next count = 0
Qn <= "000";
else --No other bits are set
Qn<="001"; --or it could be Qn<=Qp;
end if;

when "010" => --Put similar code here
when "011" => --Put similar code here
when "100" => --Put similar code here
when "101" => --Put similar code here
when "110" => --Put similar code here
when others => --Put similar code for state 7
end case;

Q<=Qp; --Output is the present state (count)

end process combinational;

sequential : process(CLK,RST,seq)
begin
if(RST='1') then
if(seq(0)='1') then
Qp<="000";
elsif(seq(1)='1') then
Qp<="001";
elsif(seq(2)='1')then
Qp<="010";
elsif(seq(3)='1') then
Qp<="011";
elsif(seq(4)='1')then
Qp<="100";
elsif(seq(5)='1') then
Qp<="101";
elsif(seq(6)='1')then
Qp<="110";
elsif(seq(7)='1')then
Qp<="111";
else --If no bit on input is set
Qp<="000"; --default to count=0
end if;

elsif(clk'event and clk='1') then
Qp <= Qn; --On rising edge, change stage
end if;

end process sequential;

end counter;
 

    TERRYWU3

    Points: 2
    Helpful Answer Positive Rating
here is one more way ... the code is in verilog.. hope you can translate it into vhdl!
Code:
module seq_counter (
   // Outputs
   count, 
   // Inputs
   clk, reset_n, seq
   );
   input clk, reset_n;
   input [7:0]seq;
   output [2:0] count;
   reg [2:0] count;
   reg [7:0] seq_r;
   reg [7:0]   mask, mask_nx;
   wire [7:0]  mask_and_seq = mask & seq_r;
   reg [7:0]   check_zero;
   wire        zero = ~|(check_zero);
   always @(posedge clk or negedge reset_n) begin
      if (!reset_n) begin
         seq_r <= 8'hff;
         mask <= 8'hff;
      end else begin
         seq_r <= seq;
         mask <= mask_nx;
      end
   end
   
   always @(/*AS*/count or mask or seq_r or zero) begin
      mask_nx = mask;
      if (zero)
        mask_nx = seq_r;
      else
        case(count)
          0 : mask_nx[0] = 1'b0;
          1 : mask_nx[1] = 1'b0;
          2 : mask_nx[2] = 1'b0;
          3 : mask_nx[3] = 1'b0;
          4 : mask_nx[4] = 1'b0;
          5 : mask_nx[5] = 1'b0;
          6 : mask_nx[6] = 1'b0;
          7 : mask_nx[7] = 1'b0;
        endcase // case(count)
   end

   always @(/*AS*/mask_and_seq) begin
      if (mask_and_seq[0])
        count = 0;
      else if (mask_and_seq[1])
        count = 1;
      else if (mask_and_seq[2])
        count = 2;
      else if (mask_and_seq[3])
        count = 3;
      else if (mask_and_seq[4])
        count = 4;
      else if (mask_and_seq[5])
        count = 5;
      else if (mask_and_seq[6])
        count = 6;
      else if (mask_and_seq[7])
        count = 7;
      else
        count = 0;
   end // always @ (...
   
   always @(/*AS*/count or seq_r) begin
      check_zero = seq_r;
      case (count)
        0 : check_zero = seq_r >> 1;
        1 : check_zero = seq_r >> 2;
        2 : check_zero = seq_r >> 3;
        3 : check_zero = seq_r >> 4;
        4 : check_zero = seq_r >> 5;
        5 : check_zero = seq_r >> 6;
        6 : check_zero = seq_r >> 7;
        7 : check_zero = seq_r >> 8;
      endcase
   end
endmodule // seq_counter

I have not tested this throughly!
 

    TERRYWU3

    Points: 2
    Helpful Answer Positive Rating
hi !
u first take the compare the bus value with those values with which ur counter starts and this comparison should be done whenever ur bus changes ot values. if the the bus has the values which are equal to those values, then start ur counter . all these can be done using a process statement

plz correct me if i am wrong

thanks and regards
deepak
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top