硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分

1. VL63 并串转换

1.题目:

设计一个模块进行并串转换,要求每四位d输为转到一位dout输出,输出valid_in表示此时的输入有效。

硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第1张图片

硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第2张图片


2.解题思路

        2.1 计数记录输出的位数。

        2.2 数据 有一个延时。

        2.3 思路就是 搞一个寄存器存储数据,然后根据数据的位数来决定 计数的大小。


3.解题代码

`timescale 1ns/1ns
module huawei5(
	input wire clk  ,
	input wire rst  ,
	input wire [3:0]d ,
	output wire valid_in ,
	output wire dout
	);

//*************code***********//
parameter s0 = 3'd0;
parameter s1 = 3'd1;
parameter s2 = 3'd2;
parameter s3 = 3'd3;
reg[3:0] cnt;
reg[3:0] data;
reg valid;

assign dout = data[3];
assign valid_in = valid;

always@(posedge clk or negedge rst)
	begin
		if(~rst)
			begin
				cnt <=s0;
				valid <=0;
				data <=0;
			end
		else
			begin
				if(cnt == s3)
					begin
						cnt <=s0;
						valid <=1;
						data <= d;
					end
				else
					begin
						cnt <= cnt +1;
						valid<=0;
						data <= {data[2:0],data[3]};
					end
			end
	end


//*************code***********//

endmodule


2.VL64 时钟切换

1.题目:

存在两个同步的倍频时钟clk0 clk1,已知clk0是clk1的二倍频,现在要设计一个切换电路,sel选择时候进行切换,要求没有毛刺。

硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第3张图片

硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第4张图片


2.解题思路

        2.1  两个同步的倍频时钟clk0 clk1,已知clk0是clk1的二倍频,属于相关时钟,避免切换时毛刺出现,只需要在组合逻辑的基础上添加下降沿触发的DFF。原理图如下:  (专业知识无语)(新手小白我也不是懂,只能查资料)

        链接:手撕代码2 | 无毛刺时钟切换 - 知乎 (zhihu.com)

        硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第5张图片

         2.2 我看这个题 需要自己看代码,了解一下。

         2.3 这个问题是关于 时钟的变化。防止出现毛刺, 就是防止信号突然变换。

         2.4 关于信号的突然变化 需要一个信号来决定是否现在输出   一个D 触发器来控制。

         2.5 主要是D触发器  有时钟,可以决定 信号是1/0  ,还有多余的口来输出相反的信号。


3.解题代码

`timescale 1ns/1ns

module huawei6(
	input    wire    clk0    ,
	input    wire    clk1    ,
	input    wire    rst     ,
	input    wire    sel     ,
	output   wire    clk_out
);
    reg q0, q1;
    
    always@(negedge clk0 or negedge rst)
        if(!rst)
            q0 <= 0;
        else 
            q0 <= ~sel & ~q1;
    
    always@(negedge clk1 or negedge rst)
        if(!rst) 
            q1 <= 0;
         else 
            q1 <= sel & ~q0;

    assign clk_out = (q0 & clk0) | (q1 & clk1);
    
endmodule



3.VL65 状态机与时钟分频

1.题目:

题目描述:    

使用状态机实现时钟分频,要求对时钟进行四分频,占空比为0.25

硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第6张图片

硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第7张图片


2.解题思路

        2.1  输出时序 1000

        2.1 使用状态机

        


3.解题代码

`timescale 1ns/1ns

module huawei7(
	input wire clk  ,
	input wire rst  ,
	output reg clk_out
);
parameter s0=2'd0;
parameter s1=2'd1;
parameter s2=2'd2;
parameter s3=2'd3;
reg[1:0]cnt;
//*************code***********//
always@(posedge clk or negedge rst)
	begin
		if(~rst)
			begin
				cnt <=s0;
			end
		else
			begin
				case (cnt)
					s0 : cnt <=s1;
					s1 : cnt <=s2;
					s2 : cnt <=s3;
					s3 : cnt <=s0;
				endcase
			end
	end

always@(posedge clk or negedge rst)
	begin
		if(~rst)
			begin
				clk_out <=0;
			end
		else
			begin
				case (cnt)
					s0 : clk_out <=1;
					default: clk_out <=0;
				endcase
			end
	end



//*************code***********//
endmodule



4.VL66 超前进位加法器

1.题目:

硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第8张图片

硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第9张图片


2.解题思路 

        2.1 暴力直接位和位 的对应相加。

        2.2 采用模块化


3.解题代码

暴力方式

`timescale 1ns/1ns

module huawei8//四位超前进位加法器
(
	input wire [3:0]A,
	input wire [3:0]B,
	output wire [4:0]OUT
);
wire[3:0] C; 
//*************code***********//
assign OUT[0]=A[0]^B[0]^1'b0;
assign OUT[1]=A[1]^B[1]^C[0];
assign OUT[2]=A[2]^B[2]^C[1];
assign OUT[3]=A[3]^B[3]^C[2];
assign OUT[4]=C[3];
assign C[0]=A[0]&B[0]|(A[0]|B[0])&1'b0;
assign C[1]=A[1]&B[1]|(A[1]|B[1])&C[0];
assign C[2]=A[2]&B[2]|(A[2]|B[2])&C[1];
assign C[3]=A[3]&B[3]|(A[3]|B[3])&C[2];

//*************code***********//
endmodule



//下面是两个子模块

module Add1  //计算 1 位数的C 
(
		input a,
		input b,
		input C_in,
		output f,
		output g,
		output p
		);
		
	assign g = a & b; 
	assign p = a | b;
	assign f = a ^ b ^ C_in;


endmodule






module CLA_4(
		input [3:0]P,
		input [3:0]G,
		input C_in,
		output [4:1]Ci,
		output Gm,
		output Pm
	);
	
endmodule

 模块化的方式

`timescale 1ns/1ns

module huawei8//四位超前进位加法器
(
	input wire [3:0]A,
	input wire [3:0]B,
	output wire [4:0]OUT
);

//*************code***********//
	wire [3:0] G,P,F;
	wire [4:1] C;

	Add1 inst0(
		.a 		(A[0]),
		.b 		(B[0]),
		.C_in 	(1'b0),
		.f 		(F[0]),
		.g 		(G[0]),
		.p 		(P[0])
	);

	genvar i;
	generate 
		for(i=1;i<4;i=i+1) begin:Add1_inst
			Add1 inst(
				.a 		(A[i]),
				.b 		(B[i]),
				.C_in 	(C[i]),
				.f 		(F[i]),
				.g 		(G[i]),
				.p 		(P[i])
			);
		end
	endgenerate

	 CLA_4 inst_cal(
		.P			(P),
		.G			(G),
		.C_in		(1'b0),
		.Ci			(C),
		.Gm			(),
		.Pm			()
	);

	assign OUT = {C[4],F};



//*************code***********//
endmodule



//下面是两个子模块

module Add1
(
		input a,
		input b,
		input C_in,
		output f,
		output g,
		output p
		);

	assign g = a & b;
	assign p = a | b;
	assign f = a ^ b ^ C_in; //sum

endmodule



module CLA_4(
		input [3:0]P,
		input [3:0]G,
		input C_in,
		output [4:1]Ci,
		output Gm,
		output Pm
	);

	assign Ci[1] = G[0] | P[0] & C_in;
	assign Ci[2] = G[1] | P[1] & (G[0] | P[0] & C_in);
	assign Ci[3] = G[2] | P[2] & (G[1] | P[1] & (G[0] | P[0] & C_in));
	assign Ci[4] = G[3] | P[3] & (G[2] | P[2] & (G[1] | P[1] & (G[0] | P[0] & C_in)));

	assign Gm = G[3] | (P[3]&G[2]) | (P[3]&P[2]&G[1]) | (P[3]&P[2]&P[1]&G[0]);
	assign Pm = P[3]&P[2]&P[1]&P[0];
	
endmodule



5.VL67 十六进制计数器

题目:

请用Verilog设计十六进制递增计数器电路,每个时钟周期递增1。

电路的接口如下图所示。Q[3:0]中,Q[3]是高位。

硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第10张图片

硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第11张图片


2. 解题代码

`timescale 1ns/1ns

module counter_16(
   input                clk   ,
   input                rst_n ,
 
   output   reg  [3:0]  Q      
);

always@(posedge clk or negedge rst_n)
    begin
        if(~rst_n)
            begin
                Q <=0;
            end
        else
            begin
                if(Q == 4'd15)
                    begin
                        Q<=0;
                    end
                else
                    begin
                        Q <= Q+1;
                    end
            end
    end

endmodule



6.VL70 序列检测器(Moore型)

1.题目:

请用Moore型状态机实现序列“1101”从左至右的不重叠检测。
电路的接口如下图所示。当检测到“1101”,Y输出一个时钟周期的高电平脉冲。

接口电路图如下:

硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第12张图片

硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第13张图片


2. 解题思路

        2.1 主要是我们采用 状态机

        2.2 注意一个 不重叠检测。 (当我们检测到不对时,直接重新开始)

        2.3 注意 检测是连续的, 数据输出需要一个延时,不是当时满足直接输出。


3.解题代码

`timescale 1ns/1ns

module det_moore(
   input                clk   ,
   input                rst_n ,
   input                din   ,
 
   output	reg         Y   
);
//状态机 (先设置状态)
parameter s0 = 5'b00000;
parameter s1 = 5'b00001;
parameter s2 = 5'b00011;
parameter s3 = 5'b00110;
parameter s4 = 5'b01101;
reg[4:0] flag;


always@(posedge clk or negedge rst_n)
    begin
        if(~rst_n)
            begin
                flag <=s0;
            end
        else
            begin
                case (flag)
                    s0 : flag <= din ? s1 : s0;
                    s1 : flag <= din ? s2 : s0;
                    s2 : flag <= din ? s0 : s3;
                    s3 : flag <= din ? s4 : s0;
                    s4 : flag <= din ? s1 : s0;
                endcase
            end
    end

always@(posedge clk or negedge rst_n)
    begin
        if(~rst_n)
            begin
                Y <=0;
            end
        else
            begin
                if(flag == s4)
                    begin
                        Y <= 1;
                    end
                else
                    begin
                        Y <=0;
                    end
            end
    end


endmodule



7.VL71 乘法与位运算

1.题目:

进行一个运算单元的电路设计,A[7:0]*11111011,尽量用最少的资源实现,写出对应的 RTL 代码。

 硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分_第14张图片


2. 解题思路

       2.1 一个简单的 乘法运算, 9'd1000_0000_0 =  8'b1111_1011 + 3'b100 + 1'b1;

        2.2 换算过来: 8'b1111_1011  =       9'd1000_0000_0  -  3'b100   -  1'b1;             

        2.2 再转换思维  数据* 8’b1111_1011 =  左移8位  - 左移 2位   - 数据*1;


3.解题代码

`timescale 1ns/1ns

module dajiang13(
    input  [7:0]    A,
    output [15:0]   B
	);
wire[15:0] A1;
//*************code***********//

// 9'b1000_0000_0 = 3'b100 + 1'b1 + 8'b1111_1011
assign A1 = {8'b0000_0000,A};
assign B = (A1<<8) - (A1 <<2)  -A1; 


//*************code***********//

endmodule

             


你可能感兴趣的:(牛客刷题,Verilog,HDL,fpga开发)