FPGA笔试12

乐鑫的笔试:
1, 请将下面这段 C 语言描述的串行处理过程,转换为单拍完成的并行处理,并用可综合的 Verilog 来描述。

unsigned char cal_table_high_first(unsigned char value) 
{
     unsigned char i; 
     unsigned char checksum = value;
          for (i=8; i>0; --i)  
            { 
                if (checksum & 0x80)
                        checksum = (checksum << 1) ^ 0x31;
                else
                        checksum = (checksum << 1);
            }
           return checksum;
}

答:

module loop(
input clk,
input rst_n,
input [7:0] value,
output reg [7:0] checksum);
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		checksum<=0;
	else
	begin
	for(i=0;i<8;i--)
		checksum<={value[6:0],1'b0}^(8{value[7]}&8'h31);
	end
end
endmodule

2, 设计一个自动饮料售卖机,共有两种饮料,其中饮料 A 每个 10 分钱,饮料 B 每个 5 分钱,硬币有 5 分和 10 分两种,并考虑找零。
要求用状态机实现,定义状态,画出状态转移图,并用 Verilog 完整描述该识别模块。

答:

module state(
input clk,
input rst_n,
input mode,//0为5fen,1为10fen
input A,//5fen
input B,//10fen
output reg okay_A,
output reg okay_B,
output reg [2:0] coin
);
reg [1:0] state;
parameter idle = 3'b00;
parameter s1 = 3'b001;
parameter s2 = 3'b010;
parameter s3 = 3'b011;
parameter s4 = 3'b100;
parameter s5 = 3'b101;

always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		state<=idle;
	else
	case(state)
	idle:
	begin
		if(!mode&&A)
		begin
			state<=s1;//投5分钱买5分钱的饮料
		end
		else if(mode&&B)
		begin
			state<=s2;//投10分钱买10分钱的饮料
		end
		else if(mode&&A)
		begin
			state<=s3;//投5分钱买10分钱的饮料
		end
		else if(!mode&&B)
		begin
			state<=s4;//投10分钱买5分钱的饮料
		end
	end
	s1:
	begin
		state<=idle;
	end
	s2:
		state<=idle;
	s3:
		state<=s5;//继续投钱
	s4:
		state<=idle;
	s5:
		state<=idle;

always@(posedge clk or negedge rst_n)
begin
	case(state):
	idle:
	begin
		okay_A<=0;		
		okay_B<=0;
		coin<=0;
	end	
	s1:
	begin
		okay_A<=1;
	end
	s2:
		okay_B<=1;
	s3:
	begin
		okay_A<=0;		
		okay_B<=0;
		coin<=0;
	end	
	s4:
	begin
		okay_A<=1;		
		okay_B<=0;
		coin<=3'd5;
	end	
	s5:
	begin
		if(A&&!B)
			okay_B<=1;
		else(!A&&B)
		begin
			okay_B<=1;
			coin<=3'd5;
		end
	end
	endcase
end
endmodule

3,设计一个序列信号发生器电路,能在CLK信号作用下周期性输出“0010110111”的序列信号

答:

module sequence_generator(
    input clk ,
    input rst_n ,
    output out_sequence 
);

reg [9:0] sequence  ; 
always@(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        sequence <= 10'b0010110111 ;
    end 
    else begin
        sequence <= {sequence[8:0],sequence[9]} ;
    end
end

assign out_sequence = sequence[9] ; 

endmodule

4,请实现对(1011001)2的序列检测功能,模块每拍并行输入2bit,且顺序为高位先输入,当检测到序列,输出一拍高电平脉冲。请用Verilog描述该模块
即检测两种情况:
(1)10_11_00_1x
(2) x1_01_10_01

答:

module test(
input [1:0] data,
output pulse);
reg [3:0] state;
reg pulse1;
reg pulse2;
parameter idle = 4'b0000;
parameter s1 = 4'b0001;
parameter s2 = 4'b0010;
parameter s3 = 4'b0011;
parameter s4 = 4'b0100;
parameter s5 = 4'b0101;
parameter s6 = 4'b0110;
parameter s7 = 4'b0111;
parameter s8 = 4'b1000;

always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		state<=idle;
	else
	begin
		case(state)
		idle:
		begin
			if(data==2'b10)
				state<=s1;
			else if(data[0]==1'b1)
				state<=s5;
		end
		s1:
		begin
			if(data==11)
				state<=s2;
			else
				state<=idle;
		end
		s2:
		begin
			if(data==2'b00)
				state<=s3;
			else
				state<=idle;
		end
		s3:
		begin
			if(data[1]=1'b1)
				state<=s4;
			else
				state<=idle;
		end
		s4:
			state<=idle;
		s5:
		begin
			if(data==2'b01)
				state<=s6;
			else
				state<=idle;
		end
		s6:
		begin
			if(data==2'b10)
				state<=s7;
			else
				state<=idle;
		end
		s7:
		begin
			if(data==2'b01)
				state<=s8;
			else
				state<=idle;
		end
		endcase
	end
end

always@(posedge clk or negedge rst_n)
begin
	case(state):
	s4:
		pulse1<=1'b1;
	s8:
		pulse1<1'b1;
	default:
		pulse1<=1'b0;
	endcase
end

always@(posedge clk or negedge rst_n)
begin
	pulse2<=pulse1;
end
assign pulse=pulse1&pulse2;
endmodule				

5,请基于f = 100Hz的Clock设计一个数字时钟,用Verilog实现以下功能
1、产生时、分、秒的计时
2、可通过3个按键来设置时、分、秒值
答:

module clock(
    input clk ,
    input rst_n ,
    input hour_set,
    input [4:0] hour_set_value ,

    input minute_set,
    input [5:0] minute_set_value ,

    input second_set ,
    input  [5:0] second_set_value ,

    output [5:0] second_out ,
    output [5:0] minute_out ,
    output [4:0] hour_out 
);

    reg [5:0] second_reg ;
    reg [5:0] minute_reg ;
    reg [4:0] hour_reg ;
    always@(posedge clk or negedge rst_n ) begin
        if(!rst_n) begin
            second_reg <= 0 ;
        end
        else if(second_set) second_reg <= second_set_value ;
        else if(second_reg == 59) second_reg <= 0;
        else second_reg <= second_reg +1 ;
    end

    always@(posedge clk or negedge rst_n ) begin
        if(!rst_n) begin
            minute_reg <= 0 ;
        end
        else if(minute_set) minute_reg <= minute_set_value ;
        else if(minute_reg == 59 && second_reg == 59) minute_reg <= 0;
        else if(second_reg == 59) minute_reg <= minute_reg +1 ;
    end

    always@(posedge clk or negedge rst_n ) begin
        if(!rst_n) begin
            hour_reg <= 0 ;
        end
        else if(hour_set) hour_reg <= hour_set_value ;
        else if(hour_reg == 23 && minute_reg == 59 && second_reg == 59)   hour_reg <= 0;
        else if(minute_reg == 59 && second_reg == 59 ) hour_reg <= hour_reg +1 ;
    end    

assign second_out =  second_reg ; 
assign minute_out =   minute_reg; 
assign hour_out =   hour_reg; 
endmodule

你可能感兴趣的:(FPGA笔试12)