首先附上傳送門

Count clock - HDLBits?

hdlbits.01xz.net

Problem 105 12-hour clock

牛刀小試

用計數器設計一個帶am/pm的12小時時鐘。該計數器通過一個CLK進行計時,用ena使能信號來驅動時鐘的遞增。

reset信號將時鐘複位為12:00 AM。 信號pm為0代表AM,為1代表PM。hh、mm和ss由兩個BCD計數器構成hours(01~12), minutes(00~59) , second(00~59)。Reset信號比enable信號有更高的優先順序,即使沒有enable信號也可以進行複位操作。

下圖所示的時序圖給出了從11:59:59 AM 到12 :00 : 00 PM的變化。

Hint

需要注意的是從11:59:59 PM 到12:00:00 AM和從12:59:59 PM到01:00:00 PM的變化。

解答與解析

module top_module
(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss
);

reg p; //0 is am, 1 is pm
reg [7:0] h;
reg [7:0] m;
reg [7:0] s;

always @ (posedge clk)
begin
if(reset) //reset to 12:00:00 AM
begin
p <= 0;
h <= 8h12;
m <= 8h00;
s <= 8h00;
end
else
begin
if(ena)
begin
if(s < 8h59)
begin
if(s[3:0] < 4h9) //s[3:0] is ones digit
begin
s[3:0] <= s[3:0] + 1h1;
end
else
begin
s[3:0] <= 0; //59->00
s[7:4] <= s[7:4] + 1h1; //tens digit
end
end
else
begin
s <= 0; //s清零
if(m < 8h59) //m同理s
begin
if(m[3:0] < 4h9)
begin
m[3:0] <= m[3:0] + 1h1;
end
else
begin
m[3:0] <= 0;
m[7:4] <= m[7:4] + 1h1;
end
end
else
begin
m <= 1h0;
if(h == 8h11) //AM / PM 轉換
p = !p;
if(h < 8h12)
begin
if(h[3:0] < 4h9)
h[3:0] <= h[3:0] + 1h1;
else
begin
h[3:0] <= 4h0;
h[7:4] <= h[7:4] + 1h1;
end
end
else
begin //hour 12 -> 1
h <= 1h1;
end
end
end
end
end
end

assign pm = p;
assign hh = h;
assign mm = m;
assign ss = s;

endmodule

Problem 106 4-bit shift register

牛刀小試

設計一個4bit非同步複位,擁有同步置位和使能的右移移位寄存器。

  • areset : 寄存器複位為0
  • load : 將data[3:0]輸入至移位寄存器中
  • ena : 使能信號控制向右移動(q[3]q[2]q[1]q[0] ---> 0q[3]q[2]q[1],q[0]在移動後消失了,原先q[3]的位置變為0)
  • q : 移位寄存器中的數據

如果ena和load同時為高,load有更高的優先順序。

解答與解析

本題為4-bit的移位寄存器,在ena信號中所舉例子可以很好說明本題要求。q[3]q[2]q[1]q[0] ---> 0q[3]q[2]q[1]。

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 or posedge areset)
begin
if(areset)
q <= 4b0;
else if (load)
q <= data;
else if (ena)
begin
q[3:0] <= {1b0, q[3:1]};
//q[3]q[2]q[1]q[0] --> 0q[3]q[2]q[1],q[0]在移動後消失了,原先q[3]的位置變為0
end
end

endmodule

Problem 107 Left/right rotator

牛刀小試

設計一個100bit的可左移或右移的移位寄存器,附帶同步置位和左移或右移的使能信號。本題中,移位寄存器在左移或右移時,不同於Problem106的補0和直接捨棄某一bit位,本題是要求在100bit內循環移動,不捨棄某一bit位同時也不補0。

比如說左移1bit,在Problem106就是補0和丟棄q[0]。而在本題中左移1bit為{q[0], q[99:1]}。

  • load:load信號將data[99:0] 輸入至寄存器內。
  • ena[1:0] 信號選擇是否移位和移位的具體方向
  • 2b01 右移一位
  • 2b10 左移一位
  • 2b00 和 2b11不移動
  • q:移位後寄存器內的數據

解答與解析

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 if (ena == 2b01)
q <= {q[0], q[99:1]};
else if (ena == 2b10)
q <= {q[98:0], q[99]};
else if (ena == 2b00 || ena == 2b11)
q <= q;
end

endmodule

Problem 108 Left/right arithmetic shift by 1 or 8

牛刀小試

設計一個64-bit帶同步置位的算術移位寄存器。該寄存器可以由amount控制來移動方向和每次移動的次數。

算術右移移位寄存器中的符號位(q [63])移位,不像是邏輯右移中進行補零的操作。而是保留符號位後再進行移位。

Hint

一個5-bit值為11000的寄存器算術右移一位後為11100, 而邏輯右移後為01100。

同樣的,一個5-bit值為01000的寄存器算術右移一位後為00100,且該寄存器邏輯右移會產生同樣的結果。

邏輯移位寄存器和算術左移移位寄存器沒有區別。

  • load : 置位信號。
  • ena : 使能信號,來選擇是否移位
  • amount : 選擇移位的方向和移位的個數
  • 2b00 : 左移1bit
  • 2』b01 : 左移8bit
  • 2b10 : 右移1bit
  • 2b11 : 右移8bit
  • q : 寄存器中哦的數據

解答與解析

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)
begin
if(load)
q <= data;
else if (ena)
begin
case(amount)
2b00 : begin
q <= {q[62:0], 1b0};
end

2b01: begin
q <= {q[55:0], 8b0};
end

2b10: begin
q <= {q[63], q[63:1]};
end

2b11: begin
q <= {{8{q[63]}}, q[63-:56]};
//算術右移是用符號位填充和q的高56位
//{{8{q[63]}}, q[63-:56]}
end
endcase
end
end

endmodule

Problem 109 5-bit LFSR

牛刀小試

線性反饋移位寄存器(LFSR)是通常帶有幾個XOR門來產生下一狀態的移位寄存器。Galois LFSR是一個特殊的移位寄存器。其中帶有"tap"位的位置與輸出位XOR產生下一個值沒有"tap"位標誌的正常移位。如果"tap"位置經過仔細選擇後,LFSR將設置為最大長度。再重複之前LFSR的最大長度為2^n-1

下圖所示LFSR為在位置5和位置3包含"tap"位的5-bit最大長度LFSR。開始為位置1,輸入為0。

設計如上圖所示LFSR,複位信號使LFSR複位為1.

module top_module(
input clk,
input reset, // Active-high synchronous reset to 5h1
output [4:0] q
);
always @ (posedge clk)
begin
if(reset)
q <= 5b00001;
else
begin
q[4] <= 1b0 ^ q[0];
q[3] <= q[4];
q[2] <= q[3] ^ q[0];
q[1] <= q[2];
q[0] <= q[1];
end
end

endmodule

推薦閱讀:

相关文章