EDA实验汇总

EDA实验汇总

实验1_简单组合电路的设计

2选1

module mux21a(a, b, s, y);
	input a, b, s;
	output y;
	assign y = s ? a : b;
endmodule

思考题

1-1、用 Verilog 设计一个 3 选 1 多路选择器,并在软件上进行仿真,得出仿真波形。

// 3选1
// 多了一个 2 位的标志位,可以取4种情况
module mux31a(a, b, c, flag, y);
    input a, b, c;
    input [1:0]flag;
    output reg y;
    always @ (a, b, c, flag)
        begin
            case(flag)
                2'b00 : y <= a;
                2'b01 : y <= b;
                2'b10 : y <= c;
                default : y <= a;
            endcase
        end
endmodule
// 4选1
module mux41a(a, b, c, d, s1, s0, y);
    input a, b, c, d;
    input s1, s0;
    output reg y;
    always @ (a, b, c, d, s1, s0)
        begin
            case({s1, s0})
                2'b00 : y <=a ;
                2'b01 : y <= b;
                2'b10 : y <= c;
                2'b11 : y <= d;
                default : y <= a;
            endcase
        end
endmodule

1-2、说明波形文件 mux21a.vwf 和仿真结果波形文件 mux21a-sim.vwf 的差别。

1.mux21a.vwf可以对输入数据进行修改,不会显示输出波形。修改输入波形数据后,输出波形不变。

2.mux21a-sim.vmf是在对输入赋值后运行生成的仿真波形文件,显示出了输出波形,这个文件是一个只读文件,不能对输入数据进行修改。

实验2_两种锁存器的设计

不能以latch命名

电平锁存器

锁存器也称寄存器、触发器,电平锁存器是使用时钟作为控制信号。

  • 在时钟的高电平期间,不锁存输入信号的值,输出等于输入
  • 在低电平期间,锁存下降沿到来时输入的值,然后输出保持不变
  • 锁存的时间是半个周期。
module latch_level(clk, d, q);
    input clk, d;
    output reg q;
    always @ (d, clk)
        if (clk)
            q <= d;
endmodule

时钟沿锁存器

时钟沿锁存器是使用时钟作为控制信号

  • 在时钟沿到来时(上升沿或者下降沿),将此时的输入值传到输出,然后保持不变,直到下一个时钟沿到来时才更新。

  • 在下一个时钟沿到来期间,输入的值无论如何变化,输出都保持不变

  • 即锁存的时间是一个时钟周期。

module latch_edge(clk, d, q)
    input clk, d;
    output reg q;
    // 上升沿
    always @ (posedge clk)
        q <= d;
endmodule

思考题

2-1、设计一个锁存器,具有电平锁存和时钟沿锁存 2 种功能。设输入信号是 CLK 和 D,输出是
Q1 和 Q2,其中 Q1 是电平锁存器的输出,Q2 是时钟沿锁存器的输出。写出设计代码,并在软件上仿
真得到仿真波形。

module latch_level_edge(CLK, D, Q1, Q2);
    input CLK, D;
    output reg Q1, Q2;
    always @ (D, CLK)
        Q1 <= D;
    always @ (posedge CLK)
        Q2 <= D;
endmodule

2-2*、试说明为什么 D 触发器具有抗干扰作用。

​ D触发器允许在CLK触发沿来到前一瞬间加入输入信号,输入端受到干扰的时间大大缩短,受干扰的可能性就降低了。D触发器也称为维持-阻塞边沿D触发器。

实验3_计数器的设计

1位十进制计数器

module cnt_10(reset, en, clk, cq, cout);
    input reset, en, clk;
    output reg [3:0]cq, cout;

    always @ (posedge reset, posedge clk)
        begin
            if (reset)
                cq <= 0;
            // en 是使能信号
            else if (en)
                begin
                    // cq 是计数值
                    // 范围是0 - 9 十进制
                    if (cq == 9)
                        cq <= 0;
                    else
                        cq <= cq + 1;
                end
        end
    always @ (reset, cq)
        begin
            if (reset)
                cout <= 0;
            // 当计数到9时候输出进位脉冲
            else if (cq == 9)
                cout <= 1;
            else 
                cout <= 0;
        end
endmodule

思考题

试设计一个 2 位十进制加法计数器(提示:如果调用本实验所设计的 1 位十进制计数器,则
需要改为时钟下降沿计数)。

下面是错误的

// 2位十进制加法计数器

module cnt_10_2bit(reset, en, clk, cq, cout);
input reset, en, clk;
	// 0 - 99 范围
	output reg [10:0]cq, cout;
	always @ (posedge reset, posedge clk)
		begin
			if (reset)
				cq <= 0;
			// en 是使能信号
			else if (en)
				begin
					// cq 是计数值
					// 0 - 99
					if (cq == 99)
						cq <= 0;
					else
						cq <= cq + 1;
				end
		end

	always @ (reset, cq)
		begin
			if (reset)
				cout <= 0;
			// 当计数到99时候输出进位脉冲
			else if (cq == 99)
				cout <= 1;
			else 
				cout <= 0;
		end
endmodule

正确如下

module	cnt_10_2bit(reset, clk, cnt0, cnt1, cout0, cout1);	     	      	      
    input reset,clk;
    output reg [3:0]cnt0;
    output reg [3:0]cnt1;
    output reg cout1, cout0;
    
    always @ (posedge reset or posedge clk)
        begin
            if(reset)
                cnt0 <= 0;
            else 
                begin
                    // 跟 1 位的一样
                    if(cnt0 == 9)
                        cnt0 <= 0;
                    else
                        cnt0 <= cnt0 + 1;
                end
        end	
    
    always @ (posedge reset or posedge clk)
        begin
            if(reset)
                cout0 <= 0;
            // 到9 就输出了
            // 到 8 这里就要输出了 9 - 1 = 8
            else if(cnt0 == 8)
                cout0 <= 1;
            else
                cout0 <= 0;
        end	

    always @ (posedge reset or posedge clk)
        begin
            if(reset)
                cnt1 <= 0;
            else if(cout0 == 1)
                begin
                    if(cnt1 == 9)
                        cnt1 <= 0;
                    else
                        cnt1 <= cnt1 + 1;
                end
        end	
    
    always @ (posedge reset or posedge clk)
        begin
            if(reset)
                cout1 <= 0;
            // 总是少 1 
            // 98 = 99 - 1 时候
            else if((cnt1 == 9) && (cnt0 == 8))
                cout1 <= 1;
            else
                cout1 <= 0;
        end	
endmodule

实验4_分频器的设计

数控分频器的设计与仿真

通过输入不同的初值,改变输出时钟信号的频率

module divider_control(clk, d, fout);
    input clk;
    input [7:0]d;
    output reg fout;
    reg cout;
    reg [7:0]cnt8;

    always @ (posedge clk)
        begin
            if (cnt8 == 8'b11111111)
                cnt8 <= d;
            else
                cnt8 <= cnt8 + 1;	
        end

    always @ (posedge clk)
        begin
            if (cnt8 == 8'b11111110)
                cout <= 1'b1;
            else
                cout <= 1'b0;
        end

    always @ (posedge cout)
        fout <= ~fout;
endmodule

一般分频器的设计

// 5分频 2/5 占空比
// 仿真波形如下图,可以看出分频时钟的周期是输入时钟周期的 5 倍
module div5_duty40(reset, clk, div5);
    input reset, clk;
    output reg div5;
    reg [2:0] cnt;

    always @ (posedge reset, posedge clk)
        begin
            if (reset)
                cnt <= 0;
            else
                begin
                   	// 分频数
                    // 5 - 1 = 4
                    if (cnt == 4)
                        cnt <= 0;
                    else
                        cnt <= cnt + 1;
                end
        end

    always @ (posedge reset, posedge clk)
        begin
            if (reset)
                div5 <= 0;
            	// 2 / 5 的占空比
            else if (cnt < 2)
                div5 <= 1;
            else
                div5 <= 0;
        end

endmodule

50M时钟分频器的设计

50MHz 的晶振比较常用,实验箱的核心板 DE1-SOC 板提供了 4 个 50MHz 的时钟(如附录二表 3-5
所示),通过分频可以产生各种需要的时钟,例如,1hz,10hz,100hz,500hz,1khz,50khz 等。
产生 50Khz 时钟的设计代码如下,其中分频比和?处的数据自己补充。

// 50Mhz的晶振
// 产生50kHz 时钟
// 1s 产生50M / 50k = 1000个
module div_50M(reset, clk, clk_50khz);
    input reset, clk;
    output reg clk_50khz;
    reg [31:0]cnt;

    always @ (posedge reset, posedge clk)
        begin
            if (reset)
                cnt <= 0;
            else 
                begin
                    if (cnt == 1000 - 1)
                        cnt <= 0;
                    else
                        cnt <= cnt + 1;
                end
        end


    always @ (posedge reset, posedge clk)
        begin
            if (reset)
                clk_50khz <= 0;
            // 0 - 499 500 - 999
            else if (cnt < 1000 / 2)
                clk_50khz <= 1;
            else
                clk_50khz <= 0;
        end
endmodule

在实验箱验证数控分频器

module div_ctr(reset, clk_50m, d, fout);
    input reset, clk_50m;
    input [7:0] d;
    output fout;

    // 50khz timer
    reg clk_50khz;
    reg [9:0] cnt;

    always @ (negedge reset, posedge clk_50m)
        begin
            if (!reset)
                cnt <= 0;
            else
                begin
                    if (cnt == 1000 - 1)
                        cnt <= 0;
                    else
                        cnt <= cnt + 1;
                end
        end

    always @ (negedge reset, posedge clk_50m)
        begin
            if (!reset)
                clk_50khz <= 0;
            else if (cnt < 1000 / 2)
                clk_50khz <= 1;
            else
                clk_50khz <= 0;
        end

    // 数控分频器
    reg fout;
    reg cout;
    reg [7:0] cnt8;
    always @ (posedge clk_50khz)
        begin
            if (cnt8 == 8'b11111111)
                cnt8 <= d;
            else
                cnt8 <= cnt8 + 1;
        end

    always @ (posedge clk_50khz)
        begin
            if (cnt8 == 8'b11111110)
                cout <= 1;
            else
                cout <= 0;
        end

    always @ (posedge cout)
        fout <= ~fout;
endmodule

思考题

4-1、 设计一个同步复位的 6 分频器,占空比是 50%,信号名规定如下:复位信号 reset,高电平
复位,输入时钟信号 clk,输出的 6 分频时钟为 div6,内部计数器为 counter。写出代码并仿真。

module div6_50duty(reset, clk, div6);
    input reset, clk;
    output reg div6;
    reg [2:0] counter;

    always @ (posedge reset, posedge clk)
        begin
            if (reset)
                counter <= 0;
            else
                begin 
                    // 6分频
                    // 6 - 1 = 5
                    if (counter == 5)
                        counter <= 0;
                    else
                        counter <= counter + 1;
                end
        end

    always @ (posedge reset, posedge clk)
        begin
            if (reset)
                div6 <= 0;
            // 50 % 占空比 
            else if (counter < 3)
                div6 <= 1;
            else
                div6 <= 0;
        end
endmodule

4-2、设计一个 1.5 分频的分频器。

image-20201121213613039

module div_1dot5(clk, reset, div1d5, clkN, clkP, count);
    input clk, reset;
    output div1d5, clkN, clkP;
    output reg [2:0] count;
    wire [2:0]shiftcount;
    reg clkP, clkN;

    assign shiftcount = 3'b001;
    always @ (posedge clk ,negedge reset)
        begin
            if(!reset)
                count <= shiftcount;
            else
                count <= {count[1:0],count[2]};
        end

    always @ (negedge clk or negedge reset)
        begin
            if(!reset)
                clkN <= 0;
            else if(count == 3'b010)
                clkN <= 1;
            else
                clkN <= 0; 
        end


    always @ (posedge clk or negedge reset)
        begin
            if(!reset)
                clkP <= 0;
            else if(count == 3'b100)
                clkP <= 1;
            else 
                clkP <= 0;  
        end
    assign div1d5 = clkP | clkN;
endmodule

2.5分频

参考

module D2div5(
    input clk,
    input reset,
    output D2div5,
    output [4:0] count,
    output clkN,
    output clkP
);
    reg [4:0] count;
    wire [4:0]shiftcount;
    reg clkP,clkN;

    assign shiftcount = 5'b00001;

    always @ (posedge clk ,negedge reset)
        if(!reset)
            count <= shiftcount;
    else
        count <= {count[3:0],count[4]};

    always @ (negedge clk or negedge reset)
        if(!reset)
            clkN <= 1'b0;
    else if(count == 5'b01000 || count == 5'b10000)
        clkN <= 1'b1;
    else clkN <= 1'b0;

    always @ (posedge clk or negedge reset)
        if(!reset)
            clkP <= 1'b0;
    else if(count == 5'b00001 || count == 5'b00010)
        clkP <= 1'b1;
    else clkP <= 1'b0;

    assign D2div5 = clkP | clkN;
endmodule

3分频50%占空比

module div3_duty50(
    input clk,
    input rst,
    output clk_div
);

    reg [2:0] cnt;
    reg clk_p;
    reg clk_n;

    always@(posedge clk or negedge rst)
        begin
            if(!rst)
                cnt<=0;
            else if(cnt==2)
                cnt<=0;
            else
                cnt<=cnt+1;
        end
    //下降沿采样上述时钟
    always@(posedge clk or negedge rst)
        begin
            if(!rst)
                clk_p<=0;
            else if(cnt==1)
                clk_p<=~clk_p;
            else if(cnt==2)
                clk_p<=~clk_p;
            else
                clk_p<=clk_p;
        end
    //下降沿采样上述时钟
    always@(negedge clk or negedge rst)
        begin
            if(!rst)
                clk_n<=0;
            else
                clk_n<=clk_p;
        end
    //产生分频时钟
    assign clk_div = clk_n | clk_p;

endmodule

4-3、利用实验箱的资源验证实验一中的选择器,可以将 a 设为 1hz,b 设为 10hz,a 和 b 可以使
用分频器产生。S 连接到拨码开关 SW0,y 连接到 LEDR0 上。
4-4、利用实验箱的资源验证实验三中的计数器,验证方案自己确定,原则上要求易于操作,易于
观察。

实验5 用原理图输入设计8位全加器

半加器

image-20201121165802908

// SO = a ^ b
// CO = a & b
module h_adder(a, b, CO, SO);
    input a, b;
    output CO, SO;
    assign SO = a ^ b;
    assign CO = a & b;
endmodule

全加器

image-20201121165815078

module f_adder_1bit(ain, bin, cin, sum, cout);
    input ain, bin, cin;
    output sum, cout;
    assign sum = ain ^ bin ^ cin;
    assign cout = (ain & bin) | (bin & cin) | (ain & cin);
endmodule

8 位全加器

image-20201121165915050

思考题

用verilog代码设计1位全加器

module f_adder_1bit(ain, bin, cin, sum, cout);
    input ain, bin, cin;
    output sum, cout;
    // 1 ^ 1 ^ 1 = 1
    // 1 ^ 0 ^ 0 = 1
    // 1 ^ 1 ^ 0 = 0
    // 0 ^ 0 ^ 0 = 1
    assign sum = ain ^ bin ^ cin;
    // 有两个 1 才行
    assign cout = (ain & bin) | (bin & cin) | (ain & cin);
endmodule
module add_1bit(
    input a, b, in,
    output c, out
);
    // out 是进位
    assign {out, c} = a + b + in;
endmodule

实验7 数码管应用电路的设计

HEX0 数码管

module decoder(seg_in,seg_en,seg_out);

	input [3:0] seg_in;
	input seg_en;
	output reg[7:0] seg_out;

	always@(seg_in or seg_en)
	begin
		case(seg_in)
			4'b0000:
				if(seg_en)  
					seg_out[7:0]=8'b1100_0000; 
				else 
					seg_out = 8'b11111111; 
			4'b0001:
				if(seg_en)  
					seg_out[7:0]=8'b1111_1001; 
				else 
					seg_out = 8'b11111111; 
			4'b0010:
				if(seg_en)  
					seg_out[7:0]=8'b1010_0100; 
				else 
					seg_out = 8'b11111111; 
			4'b0011:
				if(seg_en)  
					seg_out[7:0]=8'b1011_0000; 
				else 
					seg_out = 8'b11111111; 
			4'b0100:
				if(seg_en)  
					seg_out[7:0]=8'b1001_1001; 
				else 
					seg_out = 8'b11111111; 
			4'b0101:
				if(seg_en)  
					seg_out[7:0]=8'b1001_0010; 
				else 
					seg_out = 8'b11111111; 
			4'b0110:
				if(seg_en)  
					seg_out[7:0]=8'b1000_0010; 
				else 
					seg_out = 8'b11111111; 
			4'b0111:
				if(seg_en)  
					seg_out[7:0]=8'b1111_1000; 
				else 
					seg_out = 8'b11111111; 
			4'b1000:
				if(seg_en)  
					seg_out[7:0]=8'b1000_0000; 
				else 
					seg_out = 8'b11111111; 
			4'b1001:
				if(seg_en)  
					seg_out[7:0]=8'b1001_1000; 
				else 
					seg_out = 8'b11111111; 
			4'b1010:
				if(seg_en)  
					seg_out[7:0]=8'b1000_1000; 
				else 
					seg_out = 8'b11111111; 
			4'b1011:
				if(seg_en)  
					seg_out[7:0]=8'b1000_0011; 
				else 
					seg_out = 8'b11111111; 
			4'b1100:
				if(seg_en)  
					seg_out[7:0]=8'b1100_0110; 
				else 
					seg_out = 8'b11111111; 
			4'b1101:
				if(seg_en)  
					seg_out[7:0]=8'b1010_0001; 
				else 
					seg_out = 8'b11111111; 
			4'b1110:
				if(seg_en)  
					seg_out[7:0]=8'b1000_0110; 
				else 
					seg_out = 8'b11111111; 
			4'b1111:
				if(seg_en)  
					seg_out[7:0]=8'b1000_1110; 
				else 
					seg_out = 8'b11111111;
			default:                                            
				seg_out = 8'b11111111;                  
		endcase
	end
endmodule 

50M时钟分频器

module divider_50m(reset,
	      clk,	      
			clk_1hz,clk_10hz,clk_50hz,clk_50khz);
	     	      	      
	input reset,clk;
	output reg clk_1hz, clk_10hz, clk_50hz, clk_50khz;	
	
	// 计数器
	reg	[9:0]counter1;
	reg	[9:0]counter2;
	reg	[2:0]counter3;
	reg	[3:0]counter4;
	
	//*********** clk_50khz ***********
	// 50M / 50k = 1000
	always@(negedge reset or posedge clk)
		begin
			if(!reset)
				counter1 <= 0;
			else 
				begin
				if(counter1 == 999)
					counter1 <= 0;
				else
					counter1 <= counter1+1;
				end
		end	
		
	always@(negedge reset or posedge clk)
		begin
			if(!reset)
				clk_50khz <= 0;
			else if(counter1 < 500)
				clk_50khz <= 1;
			else
				clk_50khz <= 0;
		end	
		
	//*********  clk_50hz*******************
	// 50M / 50k = 1000
	always@(negedge reset or posedge clk_50khz)
		begin
			if(!reset)
				counter2 <= 0;
			else 
				begin
				if(counter2 == 999)
					counter2 <= 0;
				else
					counter2 <= counter2 + 1;
				end
		end	
		
	always@(negedge reset or posedge clk_50khz)
		begin
			if(!reset)
				clk_50hz <= 0;
			else if(counter2 < 500)
				clk_50hz <= 1;
			else
				clk_50hz <= 0;
		end
		
	//*********  clk_10hz*******************
	always@(negedge reset or posedge clk_50hz)
		begin
			if(!reset)
				counter3 <= 0;
			else 
				begin
				if(counter3 == 4)
					counter3 <= 0;
				else
					counter3 <= counter3 + 1;
				end
		end	
		
	always@(negedge reset or posedge clk_50hz)
		begin
			if(!reset)
				clk_10hz <= 0;
			else if(counter3 < 2)
				clk_10hz <= 1;
			else
				clk_10hz <= 0;
		end
		
	//*********  clk_1hz*******************
	always@(negedge reset or posedge clk_10hz)
		begin
			if(!reset)
				counter4 <= 0;
			else 
				begin
				if(counter4 == 9)
					counter4 <= 0;
				else
					counter4 <= counter4 + 1;
				end
		end	
		
	always@(negedge reset or posedge clk_10hz)
		begin
			if(!reset)
				clk_1hz <= 0;
			else if(counter4 < 5)
				clk_1hz <= 1;
			else
				clk_1hz <= 0;
		end	
endmodule

2位十进制计数器

module	cnt10_2bcd(reset,clk,
                   bcd0,bcd1,cout0,cout1);	     	      	      
    input	  reset,clk;
    output	[3:0]bcd0;
    output	[3:0]bcd1;
    output	cout1,cout0;
    reg			[3:0]bcd0;
    reg			[3:0]bcd1;
    reg			cout0;
    reg	      cout1;
    //******** bcd0 ***********
    always@(negedge reset or posedge clk)
        begin
            if(!reset)
                bcd0 <= 0;
            else 
                begin
                    if(bcd0==9)
                        bcd0 <= 0;
                    else
                        bcd0<= bcd0+1;
                end
        end	
    always@(negedge reset or posedge clk)
        begin
            if(!reset)
                cout0 <= 0;
            else if(bcd0==8)
                cout0<= 1;
            else
                cout0<= 0;
        end	
    //*******  bcd1 **********	
    always@(negedge reset or posedge clk)
        begin
            if(!reset)
                bcd1 <= 0;
            else if(cout0 == 1)
                begin
                    if(bcd1==9)
                        bcd1 <= 0;
                    else
                        bcd1<= bcd1+1;
                end
        end	
    always@(negedge reset or posedge clk)
        begin
            if(!reset)
                cout1 <= 0;
            else if((bcd1==9)&&(bcd0==8))
                cout1<= 1;
            else
                cout1<= 0;
        end		
endmodule

顶层模块的设计

module	counter_top(reset,clk,sel,	key_in,      
			seg_out0,seg_out1,cout);
			
	input		reset,clk,sel,	key_in;
	output[7:0]	seg_out0,  seg_out1;
	output	cout;

	wire[3:0]	bcd0,bcd1;
	wire	clk_counter,clk_1hz,clk_50hz;	
	reg	clk_key,sel_key;
	wire	seg_en = 1'b1;

	always@( posedge clk_50hz)
		begin clk_key <= key_in;sel_key <= sel;end
		
	assign clk_counter = sel_key? clk_1hz:clk_key;
	//*****  模块调用 **************
	divider_50m  div0 (.reset(reset),
							.clk(clk),	      
							.clk_1hz(clk_1hz),
							.clk_10hz(  ),
							.clk_50hz(clk_50hz),
							.clk_50khz(  )) ;	
							
	cnt10_2bcd count0 (.reset  (reset  ) ,   
							.clk    (clk_counter ) ,   
							.bcd0   (bcd0  ) ,   
							.bcd1   (bcd1 ) ,   
							.cout0  (cout  ) ,   
							.cout1  (  ) );	
						
	decoder  decoder0 (.seg_in(bcd0),
							 .seg_en(seg_en),
							 .seg_out(seg_out0));
							 
	decoder  decoder1 (.seg_in(bcd1),
							 .seg_en(seg_en),
							 .seg_out(seg_out1));
							 
endmodule

思考题

利用本实验提供的设计模块代码,做适当修改,使用 4 个数码管显示自己学号的低 4 位

// 4 位
module	counter_top(reset,   
                    seg_out0,seg_out1, seg_out2, seg_out3);

    input		reset;
    output[7:0]	seg_out0, seg_out1, seg_out2, seg_out3;
    // 从右边开始数起
    wire[3:0]	bcd0 = 2,bcd1 = 8, bcd2 = 0, bcd3 = 1; 
    wire	seg_en = 1'b1;

    decoder  decoder0 (.seg_in(bcd0),
                       .seg_en(seg_en),
                       .seg_out(seg_out0));

    decoder  decoder1 (.seg_in(bcd1),
                       .seg_en(seg_en),
                       .seg_out(seg_out1));
    decoder  decoder2 (.seg_in(bcd2),
                       .seg_en(seg_en),
                       .seg_out(seg_out2));
    decoder  decoder3 (.seg_in(bcd3),
                       .seg_en(seg_en),
                       .seg_out(seg_out3));

endmodule
// 6 位数码管
module	counter_top(reset,      
			seg_out0,seg_out1, seg_out2, seg_out3, seg_out4, seg_out5);
			
	input	reset;
	output[7:0]	seg_out0, seg_out1, seg_out2, seg_out3, seg_out4, seg_out5;

	// 从右边开始数起
	wire[3:0]	bcd0 = 2,bcd1 = 8, bcd2 = 0, bcd3 = 1, bcd4 = 1, bcd5 = 1; 
	
	// 使能信号
	wire	seg_en = 1'b1;
				
	decoder  decoder0 (.seg_in(bcd0),
							 .seg_en(seg_en),
							 .seg_out(seg_out0));
							 
	decoder  decoder1 (.seg_in(bcd1),
							 .seg_en(seg_en),
							 .seg_out(seg_out1));
							 
	decoder  decoder2 (.seg_in(bcd2),
						 .seg_en(seg_en),
						 .seg_out(seg_out2));
						 
	decoder  decoder3 (.seg_in(bcd3),
						 .seg_en(seg_en),
						 .seg_out(seg_out3));
						 
	decoder  decoder4 (.seg_in(bcd4),
						 .seg_en(seg_en),
						 .seg_out(seg_out4));
						 
	decoder  decoder5 (.seg_in(bcd5),
						 .seg_en(seg_en),
						 .seg_out(seg_out5));
							 
endmodule

实验8 用状态机实现系列检测器

使用状态机可以实现系列检测器,状态机设为 s0~s8 共 9 个状态, 当状态机进入 S8 状态时表示前
面的检测都正确,检测到所预制的系列。状态机输出 1,其他状态输出都为 0。

module fsm_detector(rst, clk, din, sout);
	input rst, clk;
	input din;
	output sout;
	parameter s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4;
	parameter s5 = 5, s6 = 6, s7 = 7, s8 = 8;
	reg [4:0] state;
	always @ (posedge rst, posedge clk)
		begin
			if(rst)
				state <= 0;
			else
				case(state)
					s0 : 
						if (din == 1'b1)
							state <= s1;
						else
							state <= 0;
					s1 : 
						if (din == 1'b1)
							state <= s2;
						else
							state <= 0;
					s2 : 
						if (din == 1'b1)
							state <= s3;
						else
							state <= 0;
					s3 : 
						if (din == 1'b1)
							state <= s4;
						else
							state <= 0;
					s4 : 
						if (din == 1'b1)
							state <= s5;
						else
							state <= 0;
					s6 : 
						if (din == 1'b1)
							state <= s7;
						else
							state <= 0;
					s7 : 
						if (din == 1'b1)
							state <= s8;
						else
							state <= 0;
					s8 : 
						state <= 0;
					default : 
						state <= 0;
				endcase
		end
		assign sout = (state == s8);

endmodule

  • 41
    点赞
  • 267
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bmNkotc2AECynaY6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值