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.
Design hint: 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.
译:
假设你正在设计一个电路来控制手机的铃声和振动马达。当电话需要从来电(input ring)响起时,您的电路必须打开振铃output ringer = 1)或电机(output motor = 1),但不能同时打开两者。如果手机处于振动模式(input vibrate_mode = 1),打开电机。否则,请打开铃声。
尝试只使用赋值语句,看看是否可以将问题描述转换为逻辑门的集合。
设计提示:在设计电路时,人们通常必须“向后”思考问题,从输出开始,然后向后工作到输入。这通常与人们思考(顺序的,命令式的)编程问题的方式相反,在编程问题中,人们会首先查看输入,然后决定一个操作(或输出)。对于顺序程序,人们通常会认为“如果(输入是___)那么(输出应该是___)”。另一方面,硬件设计师通常认为“当(输入)是___时,(输出)应该是___”。
上面的问题描述是以适合软件编程的命令式形式编写的(如果ring这样做),因此您必须将其转换为适合硬件实现的更具声明性的形式(assign ringer = ___)。能够在两种风格之间进行思考和转换是硬件设计所需的最重要的技能之一。
个人解法:
module top_module (
input ring,
input vibrate_mode,
output ringer, // Make sound
output motor // Vibrate
);
assign motor = (vibrate_mode & ring)?1:0;
assign ringer = ((~vibrate_mode) & ring)?1:0;
endmodule
官方解法
module top_module(
input ring,
input vibrate_mode,
output ringer,
output motor
);
// When should ringer be on? When (phone is ringing) and (phone is not in vibrate mode)
assign ringer = ring & ~vibrate_mode;
// When should motor be on? When (phone is ringing) and (phone is in vibrate mode)
assign motor = ring & vibrate_mode;
endmodule
分析:
明显官方解法更简洁,个人解法盲目的使用了三元运算;其实可以根据输出推算,ringer 置1的条件是 ring = 1 , vibrate_mode = 0(表示方式就是取反了); motor置一的条件是 ing = 1 , vibrate_mode = 1;
运行结果: