数电实验中的一个小题目:使用VHDL产生三位随机数,并显示在数码管上。

看到随机数,我们可以很自然地联想到M序列,也就是所谓的“伪随机序列”。M序列的知识在数电课程中都会有介绍,因此不再详细说明。

M序列的生成是利用移位寄存器和反馈电路来设计,不同长度的序列有不同的反馈函数,对应关系如下:

     由以上关系,我们先来产生一个长度为4的M序列:

library ieee;  
use ieee.std_logic_1164.all;  
use ieee.std_logic_unsigned.all;  
  
entity M is  
 port(clk,clr:in std_logic;  
      m:out std_logic_vector(3 downto 0)  
 );  
end M;  
  
architecture a of M is  
  signal temp:std_logic_vector(3 downto 0);  
begin  
  process(clk,clr)  
  begin   
     if clr='1' then temp<="0000";  
      elsif (clk'event and clk='1') then  
         if temp="0000" then temp<="0001";  
          else  
            temp(0)<=temp(0) xor temp(3);  --反馈函数  
             temp(1)<=temp(0);     
              temp(2)<=temp(1);  
              temp(3)<=temp(2);    
            end if;  
        end if;  
  end process;  
m<=temp;  
end; 

仿真结果为: 

接下来我们产生考虑使用M序列来产生0~999的随机数

        我们知道,要产生十进制数字9,需要4位的二进制数来表示,因此要产生三位十进制数字,就需要12位二进制数表示。这里我们有两种思路,第一种是产生三个4位M序列,分别来产生个、十、百位上的数字;第二种是产生一个12位M序列,将其分割为三个4位二进制数,产生三个随机数字。但第一种思路有个问题,就是需要保证三位数不一样,否则会失去“随机”的意义,因此我们使用更易于操作的第二种思路。

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

entity M is
 port(clk,clr:in std_logic;
      M1:inout std_logic_vector(3 downto 0);
		M2:inout std_logic_vector(3 downto 0);
		M3:inout std_logic_vector(3 downto 0);
		B1:out std_logic_vector(6 downto 0);
		B2:out std_logic_vector(6 downto 0);
		B3:out std_logic_vector(6 downto 0)
 );
end M;

architecture a of M is
  signal temp:std_logic_vector(11 downto 0);
  signal temp1:std_logic_vector(3 downto 0);
  signal temp2:std_logic_vector(3 downto 0);
  signal temp3:std_logic_vector(3 downto 0);

begin
p1:process(clk,clr)--产生12位M序列并分割为三个子序列
 begin 
     if clr='1' then temp<="000000000000";
	  elsif (clk'event and clk='1') then
	     if temp="000000000000" then temp<="000000000001";
		  else
	      temp(0)<=temp(0) xor temp(3) xor temp(5) xor temp(11);
			temp(1)<=temp(0);
			temp(2)<=temp(1);
			temp(3)<=temp(2);
			temp(4)<=temp(3);
			temp(5)<=temp(4);
			temp(6)<=temp(5);
			temp(7)<=temp(6);
			temp(8)<=temp(7);
			temp(9)<=temp(8);
			temp(10)<=temp(9);
			temp(11)<=temp(10);
			end if;
		end if;
  temp1<=temp(3 downto 0);
  temp2<=temp(7 downto 4);
  temp3<=temp(11 downto 8);
end process p1;

p2:process(temp1,temp2,temp3)--处理大于9的数字
begin 
    case temp1 is  
	      when"1010"=> M1<="0000";  
	      when"1011"=> M1<="0001";  
	      when"1100"=> M1<="0010";  
	      when"1101"=> M1<="0011";  
         when"1110"=> M1<="0100";  
	      when"1111"=> M1<="0101";  
         when others=> M1<=temp1;  
	 end case;  
	 case temp2 is  
	      when"1010"=> M2<="0000";  
	      when"1011"=> M2<="0001";  
	      when"1100"=> M2<="0010";  
	      when"1101"=> M2<="0011";  
	      when"1110"=> M2<="0100";  
	      when"1111"=> M2<="0101";  
	      when others=> M2<=temp2;  
	  end case;  
	  case temp3 is  
	      when"1010"=> M3<="0000";  
	      when"1011"=> M3<="0001";  
	      when"1100"=> M3<="0010";  
	      when"1101"=> M3<="0011";  
	      when"1110"=> M3<="0100";  
	      when"1111"=> M3<="0101";  
	      when others=> M3<=temp3;  
	  end case;  
end process p2;

p3:process(M1,M2,M3)--数码管译码
begin
   case M1 is
	   when"0000"=>B1<="1111110";
		when"0001"=>B1<="0110000";
		when"0010"=>B1<="1101101";
		when"0011"=>B1<="1111001";
		when"0100"=>B1<="0110011";
		when"0101"=>B1<="1011011";
		when"0110"=>B1<="1011111";
		when"0111"=>B1<="1110000";
		when"1000"=>B1<="1111111";
		when"1001"=>B1<="1111011";
		when others=>B1<="0000000";
	end case;
	case M2 is
	   when"0000"=>B2<="1111110";
		when"0001"=>B2<="0110000";
		when"0010"=>B2<="1101101";
		when"0011"=>B2<="1111001";
		when"0100"=>B2<="0110011";
		when"0101"=>B2<="1011011";
		when"0110"=>B2<="1011111";
		when"0111"=>B2<="1110000";
		when"1000"=>B2<="1111111";
		when"1001"=>B2<="1111011";
		when others=>B2<="0000000";
	end case;
	case M3 is
	   when"0000"=>B3<="1111110";
		when"0001"=>B3<="0110000";
		when"0010"=>B3<="1101101";
		when"0011"=>B3<="1111001";
		when"0100"=>B3<="0110011";
		when"0101"=>B3<="1011011";
		when"0110"=>B3<="1011111";
		when"0111"=>B3<="1110000";
		when"1000"=>B3<="1111111";
		when"1001"=>B3<="1111011";
		when others=>B3<="0000000";
	end case;
end process p3;

end;

 仿真结果:

        

我们可以看到M1、M2、M3是三个随机数的序列

 

可以看到数码管的三个输入信号B1、B2、B3的值都和M1、M2、M3相对应,说明译码的结果是正确的,接下来将三个B信号分别接到三个共阴极数码管的七个管脚上即可在数码管上产生随机数。

更多推荐

VHDL产生0~999之间的随机数