HDLbits刷题笔记

一、ringer(电话响铃)

问题描述:Suppose you are designing a circuit to control a cellphone’s ringer and vibration motor. Whenever the phone needs to ring from an incoming call (input ring), your circuit must either turn on the ringer (output ringer = 1) or the motor (output motor = 1), but not both. If the phone is in vibrate mode (input vibrate_mode = 1), turn on the motor. Otherwise, turn on the ringer.

Try to use only assign statements, to see whether you can translate a problem description into a collection of logic gates.

设计提示: When designing circuits, one often has to think of the problem “backwards”, starting from the outputs then working backwards towards the inputs. This is often the opposite of how one would think about a (sequential, imperative) programming problem, where one would look at the inputs first then decide on an action (or output). For sequential programs, one would often think “If (inputs are ___ ) then (output should be ___ )”. On the other hand, hardware designers often think “The (output should be ___ ) when (inputs are ___ )”.

The above problem description is written in an imperative form suitable for software programming (if ring then do this), so you must convert it to a more declarative form suitable for hardware implementation (assign ringer = ___). Being able to think in, and translate between, both styles is one of the most important skills needed for hardware design.

简述:非振动模式时,来电话(ring == 1)时响铃(ringer == 1);震动模式时(vibrate_mode == 1),来电话时震动(motor == 1)

用两个 assign 语句完成设计
不能用 if_else 语句,因为两种模式时并列关系,同时发生,而 if_else 是顺序执行,有先后关系。
在这里插入图片描述

module top_module (
    input ring,
    input vibrate_mode,
    output ringer,       // Make sound
    output motor         // Vibrate
);
    assign ringer = ring & (~vibrate_mode); //不是震动模式,且来电话了(ring == 1)
    assign motor = ring & vibrate_mode;  //是震动模式,且来电话了(ring == 1)
endmodule

二、3 bit population count(计数电路)

问题描述:A “population count” circuit counts the number of '1’s in an input vector. Build a population count circuit for a 3-bit input vector.

module top_module( 
    input [2:0] in,
    output [1:0] out );
    
 //方法1,真值表可得
    assign out[1] = in[0]&in[1] | in[1]&in[2] | in[0]&in[2];  
    //只要in有两位或以上为1,则out[1]为1
    assign out[0] = in[0] ^ in[1] ^ in[2];
    //assign out[0] = (~in[2] & ~in[1] & in[0]) | (~in[2] & in[1] & ~in[0]) | (in[2] & ~in[1] & ~in[0]) | (in[2] & in[1] & in[0]);的简化

//方法2
	assign out = in[0]+in[1]+in[2];
	
//方法3
	always @(*) begin
			case (in)
				3'd0: out = 2'd0;
				3'd1: out = 2'd1;
				3'd2: out = 2'd1;
				3'd3: out = 2'd2;
				3'd4: out = 2'd1;
				3'd5: out = 2'd2;
				3'd6: out = 2'd2;
				3'd7: out = 2'd3;
			endcase
		end
    
endmodule

三、gates and vectors

问题描述:You are given a four-bit input vector in[3:0]. We want to know some relationships between each bit and its neighbour:

out_both: Each bit of this output vector should indicate whether both the corresponding input bit and its neighbour to the left (higher index) are ‘1’. For example, out_both[2] should indicate if in[2] and in[3] are both 1. Since in[3] has no neighbour to the left, the answer is obvious so we don’t need to know out_both[3].(每一位和它的前一位都是1)

out_any: Each bit of this output vector should indicate whether any of the corresponding input bit and its neighbour to the right are ‘1’. For example, out_any[2] should indicate if either in[2] or in[1] are 1. Since in[0] has no neighbour to the right, the answer is obvious so we don’t need to know out_any[0].(每一位和它的低一位有一个是1)

out_different: Each bit of this output vector should indicate whether the corresponding input bit is different from its neighbour to the left. For example, out_different[2] should indicate if in[2] is different from in[3]. For this part, treat the vector as wrapping around, so in[3]'s neighbour to the left is in[0].(每一位和它的前一位相同,且认为vector是循环的,即in[3]的前一位是in[1])

知识点:vector的选择和组合

//我的解
module top_module( 
    input [3:0] in,
    output [2:0] out_both,
    output [3:1] out_any,
    output [3:0] out_different );
    
    assign out_both = {(in[2]&in[3]) , (in[1]&in[2]) , (in[0]&in[1])};
    assign out_any = {(in[3]|in[2]) , (in[2]|in[1]) , (in[1]|in[0])};
    assign out_different = {(in[3]^in[0]) , (in[2]^in[3]) , (in[1]^in[2]) , (in[0]^in[1])};

endmodule

//答案
module top_module (
	input [3:0] in,
	output [2:0] out_both,
	output [3:1] out_any,
	output [3:0] out_different
);

	// Use bitwise operators and part-select to do the entire calculation in one line of code
	// in[3:1] is this vector:   					 in[3]  in[2]  in[1]
	// in[2:0] is this vector:   					 in[2]  in[1]  in[0]
	// Bitwise-OR produces a 3 bit vector.			   |      |      |
	// Assign this 3-bit result to out_any[3:1]:	o_a[3] o_a[2] o_a[1]

	// Thus, each output bit is the OR of the input bit and its neighbour to the right:
	// e.g., out_any[1] = in[1] | in[0];	
	// Notice how this works even for long vectors.
	
	assign out_any = in[3:1] | in[2:0];

	assign out_both = in[2:0] & in[3:1];
	
	// XOR 'in' with a vector that is 'in' rotated to the right by 1 position: {in[0], in[3:1]}
	// The rotation is accomplished by using part selects[] and the concatenation operator{}.
	assign out_different = in ^ {in[0], in[3:1]};
	
endmodule

四、multiplexers(多路复用器)

1、2 to 1 multiplexer

问题描述:Create a one-bit wide, 2-to-1 multiplexer. When sel=0, choose a. When sel=1, choose b.

module top_module (
	input a,
	input b,
	input sel,
	output out
);

//方法1
	assign out = (sel & b) | (~sel & a);	// Mux expressed as AND and OR
//方法2
	assign out = sel ? b : a;
	//当a,b是多元向量时方法1不再适用,只能使用三元运算
	
endmodule

2、256 to 1, 4-bit multiplexer

问题描述: Create a 4-bit wide, 256-to-1 multiplexer. The 256 4-bit inputs are all packed into a single 1024-bit input vector. sel=0 should select bits in[3:0], sel=1 selects bits in[7:4], sel=2 selects bits in[11:8], etc.

Expected solution length: Around 1–5 lines.

提示:

  • With this many options, a case statement isn’t so useful.
  • Vector indices can be variable, as long as the synthesizer can figure out that the width of the bits being selected is constant. It’s not always good at this. An error saying “… is not a constant” means it couldn’t prove that the select width is constant. In particular, in[sel4+3 : sel4 ] does not work.
  • Bit slicing (“Indexed vector part select”, since Verilog-2001) has an even more compact syntax.
module top_module (
	input [1023:0] in,
	input [7:0] sel,
	output [3:0] out
);

	// We can't part-select multiple bits without an error, but we can select one bit at a time,
	// four times, then concatenate them together.
	assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]};

	// Alternatively, "indexed vector part select" works better, but has an unfamiliar syntax:
	// assign out = in[sel*4 +: 4];		// 选择从索引“sel*4”开始,然后选择总宽度为 4 位,并增加 (+:) 索引号。
	// assign out = in[sel*4+3 -: 4];	// 选择从索引“sel*4+3”开始,然后选择总宽度为 4 位,索引号递减 (-:)。
	// Note: The width (4 in this case) must be constant.

endmodule

五、一位全加器

//我的
module add1 ( input a, input b, input cin,   output sum, output cout );

    wire [1:0] s = a + b + cin;
    assign sum = s[0];
    assign cout = s[1]; 

endmodule
//better one 
module add1 ( input a, input b, input cin, output sum, output cout );

    assign sum=a^b^cin;
    assign cout=cout = a&b | a&cin | b&cin;
    
endmodule
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"Labuladong"是一个著名的算法题解博主,他的刷题笔记非常受欢迎。他的笔记具有以下几个特点: 1. 思路清晰:Labuladong的刷题笔记总是能够很清晰地阐述解题思路。他善于将复杂的问题简化为易于理解的小问题,并通过逐步引入关键概念和方法,帮助读者理解并掌握解题思路。 2. 逻辑严谨:Labuladong的刷题笔记经过深思熟虑,逻辑严谨。他会从问题的定义开始,逐步引入相关的概念和解题思路,循序渐进地解决问题。这种严谨的逻辑结构有助于读者理解和消化算法的核心思想。 3. 举例详细:Labuladong的刷题笔记通常会通过具体的例子来说明解题思路。这种举例的方式不仅能够帮助读者更好地理解解题方法,还可以帮助读者更好地应用这些方法解决其他类似的问题。 4. 知识点整合:Labuladong的刷题笔记不仅仅是一个题解,而是将相关的算法知识点整合起来,构建出一个完整的学习体系。他会引入一些底层的算法原理,将不同的解题方法进行比较和总结。这种整合的方式能够帮助读者更好地理解和掌握算法的本质。 总之,Labuladong的刷题笔记以其思路清晰、逻辑严谨、举例详细和知识点整合等特点,为广大读者提供了一种深入学习和理解算法的有效途径。通过阅读他的刷题笔记并进行实践,读者能够提高解题能力,并在面对各种算法问题时能够找到正确、高效的解决方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值