HDL-Bits 刷题记录 03
首发csdn
ece241 2014 q7b3
给一个1kHZ的时钟,要一个1000倍的分频器,输出要一个1HZ 的时钟给了一个bcd计数器module
module bcdcount (
input clk,
input reset,
input enable,
output reg [3:0] Q
);
module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable
); //
reg [3:0] Q1,Q2,Q3;
always @(*) begin
c_enable[0] = 1'b1;
if(Q1==4'd9)
c_enable[1] = 1'b1;
else
c_enable[1] = 1'b0;
if(Q1==4'd9 && Q2==4'd9)
c_enable[2] = 1'b1;
else
c_enable[2] = 1'b0;
end
assign OneHertz = (Q1==4'd9 && Q2==4'd9 && Q3==4'd9);
bcdcount counter0 (clk, reset, c_enable[0],Q1);
bcdcount counter1 (clk, reset, c_enable[1],Q2);
bcdcount counter2 (clk, reset, c_enable[2],Q3);
endmodule
Countbcd
同步时钟,在9,99,999时候进位给ena
BCD码 4位一个十进制数 十进制数为0-9
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:1] ena,
output [15:0] q);
assign ena[1] = (q[3:0]==4'd9) ? 1:0;
assign ena[2] = (q[7:4]==4'd9&&q[3:0]==4'd9) ? 1:0;
assign ena[3] = (q[11:8]==4'd9&&q[7:4]==4'd9&&q[3:0]==4'd9) ? 1:0;
always@(posedge clk )begin
if(reset) begin
//ena <= 3'd0;
q <= 15'd0;
end
else if(q[3:0]==4'd9 && q[7:4]==4'd9 && q[11:8]==4'd9 && q[15:12]==4'd9) begin
q <= 16'd0;
//ena <= 3'd0;
end
else if(q[3:0]==4'd9 && q[7:4]==4'd9 && q[11:8]==4'd9 ) begin
q[11:0] <= 12'd0;
q[15:12] <= q[15:12] + 1;
//ena <= 3'b111;
end
else if(q[3:0]==4'd9 && q[7:4]==4'd9) begin
q[7:0] <= 8'd0;
q[11:8] <= q[11:8] + 1;
//ena <= 3'b011;
end
else if(q[3:0]==4'd9) begin
q[3:0] <= 4'd0;
q[7:4] <= q[7:4] + 1;
end
else begin
q[3:0] <= q[3:0]+1;
//ena <= 3'b000;
end
end
endmodule
Countbcd
一组适合用作 12 小时制的计数器(带有上午/下午指示器)
pm = 0是上午(AM)
pm = 1是下午(PM)
hh, mm, ss两位BCD码表示小时(01-12), 分钟(00-59),秒(00-59). Reset比enable权限高,当不使能时也可以复位.
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
always@(posedge clk)begin
if(reset) begin
hh <= 8'h12;
mm <= 8'h00;
ss <= 8'h00;
pm <= 1'b0;
end
else if (hh == 8'h12&&mm==8'h59&&ss==8'h59&&ena) begin
hh <= 8'h01;
mm <= 8'h00;
ss <= 8'h00;
end
else if (hh == 8'h11&&mm==8'h59&&ss==8'h59&&ena) begin
pm <= ~pm;
hh <= 8'h12;
mm <= 8'h00;
ss <= 8'h00;
end
else if (hh == 8'h9&&mm==8'h59&&ss==8'h59&&ena) begin
hh <= 8'h10;
mm <= 8'h00;
ss <= 8'h00;
end
else if (mm==8'h59&&ss==8'h59&&ena) begin
hh[3:0] <= hh[3:0] + 1;
mm <= 8'h00;
ss <= 8'h00;
end
else if (mm[3:0]==4'h9&&ss==8'h59&&ena) begin
mm[7:4] <= mm[7:4] + 1;
mm[3:0] <= 4'h0;
ss <= 8'h00;
end
else if (ss==8'h59&&ena) begin
mm[3:0] <= mm[3:0] + 1;
ss <= 8'h00;
end
else if (ss[3:0]==4'h9&&ena) begin
ss[7:4] <= ss[7:4] + 4'h01;
ss[3:0] <= 4'h00;
end
else if (ena) begin
ss[3:0] <= ss[3:0] + 4'h01;
end
end
endmodule
Shift Registers
Shift4
4位右移寄存器
高电平复位为0
load将输入的data全部导入
ena 使能向右移位 高位为0 低位消失
q 输出
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) begin
q <= 4'd0;
end
else if (load) begin
q <= data;
end
else if (ena) begin
q <= q>>1;
end
end
endmodule
Rotate100
100bit 循环左右移寄存器 左移低位补最高位,右移高位补最低位
ena : 01 右移移位,10 左移一位
load 载入data
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) begin
q <= data;
end
else if (ena == 2'b01) begin
q <= {q[0],q[99:1]};
end
else if (ena == 2'b10) begin
q <= {q[98:0],q[99]};
end
else
q <= q;
end
endmodule
Shift18
算术移位
amount 00: 左移一位,01: 左移8 位,10 右移1位,11 右移8位
左移正常操作,右移保留符号位,特殊情况,符号位如果为1,右移拉出来一排(7个)1
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) begin
q <= data;
end
else if (amount == 2'b00 &&ena) begin
q <= {q[62:0],1'b0};
end
else if (amount == 2'b01&&ena) begin
q <= {q[55:0],8'd0};
end
else if (amount == 2'b11&&ena) begin
q <= {q[63],{7{q[63]}},q[63:8]};//重复拼接
end
else if (amount == 2'b10&&ena) begin
q <= {q[63],q[63],q[62:1]};
end
else
q <= q;
end
endmodule
Lfsr5
线性反馈移位寄存器是一种移位寄存器,通常带有几个异或门来产生移位寄存器的下一个状态
描述看不懂 上图
复位给1 其他的看不懂
module top_module(
input clk,
input reset, // Active-high synchronous reset to 5'h1
output [4:0] q
);
always@(posedge clk) begin
if(reset )
q <= 4'd1;
else begin
q[4] <= 0^q[0];
q[3] <= q[4];
q[2] <= q[3]^q[0];
q[1] <= q[2];
q[0] <= q[1];
end
end
endmodule
Mt2015 lfsr
module top_module (
input [2:0] SW, // R
input [1:0] KEY, // L and clk
output [2:0] LEDR); // Q
reg [2:0] D;
assign D[0] = KEY[1]?SW[0]:LEDR[2];
assign D[1] = KEY[1]?SW[1]:LEDR[0];
assign D[2] = KEY[1]?SW[2]:(LEDR[1]^LEDR[2]);
always@(posedge KEY[0]) begin
LEDR[0] <= D[0];
LEDR[1] <= D[1];
LEDR[2] <= D[2];
end
endmodule
Lfsr32
应该有好的方案,暂时不想想
module top_module(
input clk,
input reset, // Active-high synchronous reset to 32'h1
output [31:0] q
);
always@(posedge clk) begin
if(reset )
q <= 4'd1;
else begin
q[31] <= q[0]^0;
q[30] <= q[31];
q[29] <= q[30];
q[28] <= q[29];
q[27] <= q[28];
q[26] <= q[27];
q[25] <= q[26];
q[24] <= q[25];
q[23] <= q[24];
q[22] <= q[23];
q[21] <= q[22]^q[0];
q[20] <= q[21];
q[19] <= q[20];
q[18] <= q[19];
q[17] <= q[18];
q[16] <= q[17];
q[15] <= q[16];
q[14] <= q[15];
q[13] <= q[14];
q[12] <= q[13];
q[11] <= q[12];
q[10] <= q[11];
q[9] <= q[10];
q[8] <= q[9];
q[7] <= q[8];
q[6] <= q[7];
q[5] <= q[6];
q[4] <= q[5];
q[3] <= q[4];
q[2] <= q[3];
q[1] <= q[2]^q[0];
q[0] <= q[1]^q[0];
end
end
endmodule
m2014 q4k
module top_module (
input clk,
input resetn, // synchronous reset
input in,
output out);
assign out = D[3];
reg [3:0] D;
always@(posedge clk) begin
if(!resetn )
D <= 4'b0;
else begin
D[0] <= in;
D[3:1] <= D[2:0];
end
end
endmodule
2014 q4b
MUXDFF定义的是带两个数选的D触发器,然后例化了一个数组,输入首位拼接
- 将R输入连接到SW开关,
- clk到KEY[0] ,
- E到KEY[1] ,
- L到KEY[2],并且
- w到KEY[3]。
- 将输出连接到红灯LEDR[3:0]。
module top_module (
input [3:0] SW,
input [3:0] KEY,
output [3:0] LEDR
); //
MUXDFF mux4[3:0](
.E({4{KEY[1]}}),
.R(SW[3:0]),
.L({4{KEY[2]}}),
.w({KEY[3],LEDR[3:1]}),
.clk({4{KEY[0]}}),
.Q(LEDR[3:0]),
);
endmodule
module MUXDFF (
input E,
input R,
input L,
input w,
input clk,
output Q
);
reg D;
assign D = L?R:(E?w:Q);
always@(posedge clk) begin
Q <= D;
end
endmodule
ece241 2013 q12
您将为 8x1 存储器设计一个电路,其中写入存储器是通过移入位来完成的,而读取是“随机访问”,就像在典型的 RAM 中一样。然后,您将使用该电路实现 3 输入逻辑功能。
首先,创建一个带有 8 个 D 型触发器的 8 位移位寄存器。标记来自 Q[0]...Q[7] 的触发器输出。移位寄存器输入应称为S,它馈入 Q[0] 的输入(首先移入 MSB)。使能输入控制是否移位。然后,将电路扩展为具有 3 个附加输入A、B、C和一个输出Z。电路的行为应该如下:当 ABC 为 000 时,Z=Q[0],当 ABC 为 001 时,Z=Q[1],依此类推。您的电路应该只包含 8 位移位寄存器和多路复用器。(注:该电路称为 3 输入查找表 (LUT))
[喵了个咪的不给图是真的恶心 看不懂 ]
module top_module (
input clk,
input enable,
input S,
input A, B, C,
output Z );
reg [7:0] Q;
assign Z = Q[{A,B,C}];
DFF1 DFF16[7:0](
.data({Q[6:0],S}),
.clk({8{clk}}),
.en({8{enable}}),
.Q(Q[7:0])
);
endmodule
module DFF1 (
input data,
input clk,
input en,
output Q
);
always@(posedge clk) begin
if(en)
Q <= data;
else
Q <= Q;
end
endmodule
下面是官方答案,真滴简洁....
感觉我就是个垒代码的fw
module top_module (
input clk,
input enable,
input S,
input A, B, C,
output reg Z
);
reg [7:0] q;
// The final circuit is a shift register attached to a 8-to-1 mux.
// Create a 8-to-1 mux that chooses one of the bits of q based on the three-bit number {A,B,C}:
// There are many other ways you could write a 8-to-1 mux
// (e.g., combinational always block -> case statement with 8 cases).
assign Z = q[ {A, B, C} ];
// Edge-triggered always block: This is a standard shift register (named q) with enable.
// When enabled, shift to the left by 1 (discarding q[7] and and shifting in S).
always @(posedge clk) begin
if (enable)
q <= {q[6:0], S};
end
endmodule