第一題:Build a 4-bit shift register (right shift), with asynchronous reset, synchronous load, and enable.
- areset: Resets shift register to zero.
- load: Loads shift register with data[3:0] instead of shifting.
- ena: Shift right (q[3] becomes zero, q[0] is shifted out and disappears).
- q: The contents of the shift register.
If both the load and ena inputs are asserted (1), the load input has higher priority.
module top_module(
input clk,
input areset, // async active-high reset to zero
input load,
input ena,
input [3:0] data,
output reg [3:0] q);
always@(posedge clk,posedge areset)
if(areset)
q <= 0;
else if(load)
q <= data;
else if(ena)
q <= {1'd0,q[3:1]};
endmodule
------------------------/*官網(wǎng)參考答案*/-----------------------------
module top_module(
input clk,
input areset,
input load,
input ena,
input [3:0] data,
output reg [3:0] q);
// Asynchronous reset: Notice the sensitivity list.
// The shift register has four modes:
// reset
// load
// enable shift
// idle -- preserve q (i.e., DFFs)
always @(posedge clk, posedge areset) begin
if (areset) // reset
q <= 0;
else if (load) // load
q <= data;
else if (ena) // shift is enabled
q <= q[3:1]; // Use vector part select to express a shift.
end
endmodule
第二題:Build a 100-bit left/right rotator, with synchronous load and left/right enable. A rotator shifts-in the shifted-out bit from the other end of the register, unlike a shifter that discards the shifted-out bit and shifts in a zero. If enabled, a rotator rotates the bits around and does not modify/discard them.
- load: Loads shift register with data[99:0] instead of rotating.
- ena[1:0]: Chooses whether and which direction to rotate.
2'b01 rotates right by one bit
2'b10 rotates left by one bit
2'b00 and 2'b11 do not rotate. - q: The contents of the rotator.
module top_module(
input clk,
input load,
input [1:0] ena,
input [99:0] data,
output reg [99:0] q);
always@(posedge clk) begin
if(load) q<= data;
else begin
case(ena)
2'b01: q<={q[0],q[99:1]};
2'b10: q<={q[98:0],q[99]};
2'b00: q<=q;
2'b11:q<=q;
endcase
end
end
endmodule
- --------------------------官網(wǎng)參考答案 --------------------
module top_module(
input clk,
input load,
input [1:0] ena,
input [99:0] data,
output reg [99:0] q);
// This rotator has 4 modes:
// load
// rotate left
// rotate right
// do nothing
// I used vector part-select and concatenation to express a rotation.
// Edge-sensitive always block: Use non-blocking assignments.
always @(posedge clk) begin
if (load) // Load
q <= data;
else if (ena == 2'h1) // Rotate right
q <= {q[0], q[99:1]};
else if (ena == 2'h2) // Rotate left
q <= {q[98:0], q[99]};
end
endmodule
第三題:Build a 64-bit arithmetic shift register, with synchronous load. The shifter can shift both left and right, and by 1 or 8 bit positions, selected by amount.
An arithmetic right shift shifts in the sign bit of the number in the shift register (q[63] in this case) instead of zero as done by a logical right shift. Another way of thinking about an arithmetic right shift is that it assumes the number being shifted is signed and preserves the sign, so that arithmetic right shift divides a signed number by a power of two.
There is no difference between logical and arithmetic left shifts.
module top_module(
input clk,
input load,
input ena,
input [1:0] amount,
input [63:0] data,
output reg [63:0] q);
always@(posedge clk)
if(load)
q <= data;
else if(ena)
case(amount)
2'b00 : q <= {q[62:0],1'd0};
2'b01 : q <= {q[55:0],8'd0};
2'b10 : q <= {q[63],q[63:1]};
2'b11 : q <= {{8{q[63]}},q[63:8]};
endcase
endmodule
第四題:有序狀態(tài)機(jī)的一道入門題较锡。感覺自己對(duì)有限狀態(tài)機(jī)的理解還是不夠好煤杀!
題目給定的是莫爾型狀態(tài)機(jī)景馁,在這里,首先需要清楚一個(gè)概念 :即根據(jù)輸出信號(hào)的產(chǎn)生:有限狀態(tài)機(jī)分為兩種:
- Mealy(米利型):Mealy型狀態(tài)機(jī)的輸出與當(dāng)前狀態(tài)和輸入有關(guān)系;
- Moore(莫爾型) :Moore型狀態(tài)機(jī)僅與當(dāng)前狀態(tài)有關(guān)纸颜,而與輸出無關(guān)绍绘。
對(duì)于狀態(tài)機(jī)的寫法,常用的有兩段式和三段式褐耳;
不過一般建議用三段式編寫诈闺,比較方便易,讀
module top_module(
input clk,
input areset, // Asynchronous reset to state B
input in,
output out);//
parameter A=0, B=1;
reg state, next_state;
always @(*) begin // This is a combinational always block
case(state)
A: if(in)
next_state <= A;
else
next_state <= B;// State transition logic
B: if(in)
next_state <= B;
else
next_state <= A;
endcase
end
always @(posedge clk, posedge areset) begin // This is a sequential always block
if(areset)
state <= B;
else
state <= next_state;// State flip-flops with asynchronous reset
end
assign out = state == B ? 1: 0;
// Output logic
// assign out = (state == ...);
endmodule
------------------------------------官網(wǎng)參考答案---------------------------------
module top_module (
input clk,
input in,
input areset,
output out
);
// Give state names and assignments. I'm lazy, so I like to use decimal numbers.
// It doesn't really matter what assignment is used, as long as they're unique.
parameter A=0, B=1;
reg state; // Ensure state and next are big enough to hold the state encoding.
reg next;
// A finite state machine is usually coded in three parts:
// State transition logic 狀態(tài)轉(zhuǎn)移方程
// State flip-flops 激勵(lì)方程
// Output logic 輸出方程
// It is sometimes possible to combine one or more of these blobs of code
// together, but be careful: Some blobs are combinational circuits, while some
// are clocked (DFFs).
// Combinational always block for state transition logic. Given the current state and inputs,
// what should be next state be?
// Combinational always block: Use blocking assignments.
always@(*) begin
case (state)
A: next = in ? A : B;
B: next = in ? B : A;
endcase
end
// Edge-triggered always block (DFFs) for state flip-flops. Asynchronous reset.
always @(posedge clk, posedge areset) begin
if (areset) state <= B; // Reset to state B
else state <= next; // Otherwise, cause the state to transition
end
// Combinational output logic. In this problem, an assign statement is the simplest.
// In more complex circuits, a combinational always block may be more suitable.
assign out = (state==B);
endmodule
/*這里不能使用非阻塞賦值語句的原因沒有搞懂*/
// Note the Verilog-1995 module declaration syntax here:
module top_module(clk, reset, in, out);
input clk;
input reset; // Synchronous reset to state B
input in;
output out;//
reg out;
parameter A=0,B=1; // Fill in state name declarations
reg present_state, next_state;
always @(posedge clk) begin
if (reset) begin
// Fill in reset logic
out <= B;
present_state <= B;
end else begin
case (present_state)
// Fill in state transition logic
A:
if(in) next_state = A;
else next_state = B;
B:
if(in) next_state = B;
else next_state = A;
endcase
// State flip-flops
present_state = next_state;
case (present_state)
// Fill in output logic
A:out = A;
B:out = B;
endcase
end
end
endmodule