99. Four-bit binary counter
没什么说的
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
initial q = 4'b0;
always @(posedge clk)
begin
if(reset) q <= 4'h0;
else
begin
if(q == 4'hf) q = 4'h0;
else q = q + 1'b1;
end
end
endmodule
102. Count slow
if和else if
module top_module (
input clk,
input slowena,
input reset,
output [3:0] q);
initial q = 4'h0;
always @(posedge clk)
begin
if(reset) q <= 4'h0;
else if(slowena)
begin
q <= q + 1'b1;
if(q == 4'd9) q <= 4'h0;
end
end
endmodule
103.Counter 1-12
错误代码:
module top_module (
input clk,
input reset,
input enable,
output [3:0] Q,
output reg c_enable,
output reg c_load,
output reg [3:0] c_d
);
initial
begin
c_load = 1'b0;
c_enable = 1'b1;
Q = 4'd0;
end
always @(posedge clk)
begin
if(reset)
begin
c_load <= 1'b1;
c_d <= 4'd1;
end
else if(enable)
begin
begin
c_load = 1'b0;
c_enable = 1'b1;
end
end
else
c_enable = 1'b0;
end
count4 the_counter (clk, c_enable, c_load, c_d, Q);
endmodule
错误分析:总是滞后一个周期,是因为always在clk上升沿改变状态,因此下个上升沿才会改变the_counter状态。因此需要用assign 直接连接电路,实时改变状态,在第一个上升沿到来时就改变counter 状态。
正确代码:
module top_module (
input clk,
input reset,
input enable,
output [3:0] Q,
output c_enable,
output c_load,
output [3:0] c_d
); //
assign c_enable = enable;
assign c_load = reset | ((Q == 4'd12) && enable == 1'b1);
assign c_d = c_load ? 4'd1 : 4'dz;
count4 u_counter (clk, c_enable, c_load, c_d, Q);
endmodule
20210412:
104.Counter 1000
c_enable[1] , c_enable[2] 务必与低位相与。先画出想象中的4路Q输出,对应个十百千位,再写enable.
module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable
); //
wire [3:0] Q0, Q1, Q2, Q3;
assign c_enable[0] = 1'b1;
assign c_enable[1] = Q0[0] & Q0[3];
assign c_enable[2] = (Q1[0] & Q1[3]) & c_enable[1];
assign OneHertz = (Q2[0] & Q2[3]) & c_enable[2];
bcdcount counter0 (clk, reset, c_enable[0], Q0);
bcdcount counter1 (clk, reset, c_enable[1], Q1);
bcdcount counter2 (clk, reset, c_enable[2], Q2);
bcdcount counter3 (clk, reset, OneHertz, Q3);
endmodule
105.4-digital decimal counter
always中clk不写posedge会报错:
Error (23031): Evaluation of Tcl script /home/h/hdlbits/compile.tcl unsuccessful
Error: Quartus Prime Shell was unsuccessful. 1 error, 6 warnings
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:1] ena,
output [15:0] q);
assign ena[1] = q[3] & q[0];
assign ena[2] = (q[7] & q[4]) & ena[1];
assign ena[3] = (q[11] & q[8]) & ena[2];
cnt cnt0(clk, reset, 1'b1, q[3:0]);
cnt cnt1(clk, reset, ena[1], q[7:4]);
cnt cnt2(clk, reset, ena[2], q[11:8]);
cnt cnt3(clk, reset, ena[3], q[15:12]);
endmodule
module cnt(
input clk,
input reset,
input enable,
output reg [3:0]q
);
always@(posedge clk)
begin
if(reset) q = 4'd0;
else if(enable)
begin
if(q == 4'd9) q = 4'd0;
else q = q + 4'd1;
end
end
endmodule
20210413
106.12-hour clock
分秒和时针分开写,分秒:59-00;时针:01-09-12-01;因为是十六进制,用低四位高四位表示,进位信息作为输入。
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
wire ena1, ena2, ena3, ena4;
assign ena1 = (ss[3:0] == 4'h9) & ena;
assign ena2 = (ss[7:4] == 4'h5) & ena1;
assign ena3 = (mm[3:0] == 4'h9) & ena2;
assign ena4 = (mm[7:4] == 4'h5) & ena3;
cnt cnt0 (clk, reset, ena, 4'd0, 4'd0, 4'd9, ss[3:0]);
cnt cnt1 (clk, reset, ena1, 4'd0, 4'd0, 4'd5, ss[7:4]);
cnt cnt2 (clk, reset, ena2, 4'd0, 4'd0, 4'd9, mm[3:0]);
cnt cnt3 (clk, reset, ena3, 4'd0, 4'd0, 4'd5, mm[7:4]);
cnthh cnt4 (clk, reset, ena4, hh[7:0]);
always@(posedge clk)
begin
if(reset) pm = 1'b0;
else if(ena4 & (hh == 8'h11))
pm = ~pm;
end
endmodule
module cnt(
input clk,
input reset,
input ena,
input [3:0] start,
input [3:0] renum,
input [3:0] radix,
output reg [3:0] q
);
always@(posedge clk)
begin
if(reset) q = renum;
else if(ena)
begin
if(q == radix) q = start;
else q = q + 1'b1;
end
end
endmodule
module cnthh(
input clk,
input reset,
input ena,
output reg [7:0] q
);
always@(posedge clk)
begin
if(reset) q = 8'h12;
else if(ena)
begin
if(q[7:4] == 0)
begin
if(q[3:0] == 4'd9)
begin
q[3:0] = 4'd0;
q[7:4] = 4'd1;
end
else q[3:0] = q[3:0] + 4'b1;
end
else
begin
if(q[3:0] == 4'd2)
begin
q[3:0] = 4'd1;
q[7:4] = 4'd0;
end
else q[3:0] = q[3:0] + 4'b1;
end
end
end
endmodule
107.4-bit shift register
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 = 0;
else if(load)
q = data;
else if(ena)
begin
q = {1'b0, q[3], q[2], q[1]};
end
end
endmodule
108. Left/right 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]};
default;
endcase
end
end
endmodule
109.Left/right arthimetic shift by 1 or 8
算数右移保留符号位,移动后左侧全为符号位。
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)
2'b00 : q = {q[62:0], 1'b0};
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]};
default;
endcase
end
end
endmodule
110. 5-bit LFSR(linear feedback shift register )
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 = 5'h1;
else
begin
q = {(q[0] ^ 1'b0), q[4], (q[3] ^ q[0]), q[2], q[1]};
end
end
endmodule
111. 3-bit LFSR
module top_module (
input [2:0] SW, // R
input [1:0] KEY, // L and clk
output [2:0] LEDR); // Q
always@(posedge KEY[0])
begin
if(KEY[1])
LEDR = {SW};
else
LEDR = {LEDR[1] ^ LEDR[2], LEDR[0], LEDR[2]};
end
endmodule
112. 32-bit LFSR
为什么右移? position32指什么?
module top_module(
input clk,
input reset, // Active-high synchronous reset to 32'h1
output [31:0] q
);
reg [31:0] q_up;
always@(posedge clk)
begin
if(reset) q <= 32'h1;
else
begin
q_up = {q[0], q[31:1]};
q_up[21] = q[22] ^ q[0];
q_up[1] = q[2] ^ q[0];
q_up[0] = q[1] ^ q[0];
q = q_up;
end
end
endmodule
113.Shift register
module top_module (
input clk,
input resetn, // synchronous reset
input in,
output out);
reg q2, q1, q0;
always@(posedge clk)
begin
if(!resetn)
{out, q2, q1, q0} = 4'b0;
else
{out, q2, q1, q0} = {q2, q1, q0, in};
end
endmodule
20210414
114.Shift register
module top_module (
input [3:0] SW,
input [3:0] KEY,
output [3:0] LEDR
); //
MUXDFF mux0(KEY[0], KEY[1], KEY[2], KEY[3], SW[3], LEDR[3]);
MUXDFF mux1(KEY[0], KEY[1], KEY[2], LEDR[3], SW[2], LEDR[2]);
MUXDFF mux2(KEY[0], KEY[1], KEY[2], LEDR[2], SW[1], LEDR[1]);
MUXDFF mux3(KEY[0], KEY[1], KEY[2], LEDR[1], SW[0], LEDR[0]);
endmodule
module MUXDFF (
input clk,
input e,
input l,
input w,
input r,
output reg q
);
always@(posedge clk)
begin
if(e)
begin
if(l) q = r;
else q = w;
end
else
begin
if(l) q = r;
else q = q;
end
end
endmodule
115. 3-input LUT( look-up-table 查找表)
分清楚组合电路和时序电路,其中Z的查找是组合电路,要么按笔者assign写,要么用always@(*)来写,切忌用clk边沿触发写组合电路,会出现延时。笔者刚开始就犯了这个错误。
module top_module (
input clk,
input enable,
input S,
input A, B, C,
output Z );
reg [7:0] q;
always@(posedge clk)
begin
if(enable)
q <= {q[6:0], S};
else q <= q;
end
assign Z = q[{A, B, C}];
endmodule
116. Rule90(元胞自动机)
module top_module(
input clk,
input load,
input [511:0] data,
output reg [511:0] q );
integer i;
always@(posedge clk)
begin
if(load) q <= data;
else
begin
q[0] <= q[1] ^ 0;
q[511] <= q[510] ^ 0;
for(i = 1; i < 511; i = i + 1)
begin
q[i] <= q[i - 1] ^ q[i + 1];
end
end
end
endmodule
116. Rule 110
这道题应该先卡诺图化简的,笔者做的比较繁琐。
module top_module(
input clk,
input load,
input [511:0] data,
output reg [511:0] q
);
integer i;
always@(posedge clk)
begin
if(load) q = data;
else
begin
case ({q[1], q[0], 1'b0})
3'b000 : q[0] <= 1'b0;
3'b001 : q[0] <= 1'b1;
3'b010 : q[0] <= 1'b1;
3'b011 : q[0] <= 1'b1;
3'b100 : q[0] <= 1'b0;
3'b101 : q[0] <= 1'b1;
3'b110 : q[0] <= 1'b1;
3'b111 : q[0] <= 1'b0;
default;
endcase
case ({1'b0, q[511], q[510]})
3'b000 : q[511] <= 1'b0;
3'b001 : q[511] <= 1'b1;
3'b010 : q[511] <= 1'b1;
3'b011 : q[511] <= 1'b1;
3'b100 : q[511] <= 1'b0;
3'b101 : q[511] <= 1'b1;
3'b110 : q[511] <= 1'b1;
3'b111 : q[511] <= 1'b0;
default;
endcase
for(i = 1; i < 511; i = i + 1)
begin
case ({q[i + 1], q[i], q[i - 1]})
3'b000 : q[i] <= 1'b0;
3'b001 : q[i] <= 1'b1;
3'b010 : q[i] <= 1'b1;
3'b011 : q[i] <= 1'b1;
3'b100 : q[i] <= 1'b0;
3'b101 : q[i] <= 1'b1;
3'b110 : q[i] <= 1'b1;
3'b111 : q[i] <= 1'b0;
default;
endcase
end
end
end
endmodule
117. Game
抄的,处理好四边即可,数学运算。
module top_module(
input clk,
input load,
input [255:0] data,
output [255:0] q );
reg [3:0] sum;
integer i;
always@(posedge clk)begin
if(load)begin
q <= data;
end
else begin
for(i = 0; i <= 255; i = i + 1)begin
if(i == 0)begin
sum = q[255] + q[240] + q[241] + q[15] + q[1] + q[31] + q[16] + q[17];
end
else if(i == 15)begin
sum = q[254] + q[255] + q[240] + q[14] + q[0] + q[30] + q[31] + q[16];
end
else if(i == 240)begin
sum = q[239] + q[224] + q[225] + q[255] + q[241] + q[15] + q[0] + q[1];
end
else if(i == 255)begin
sum = q[238] + q[239] + q[224] + q[254] + q[240] + q[14] + q[15] + q[0];
end
else if(i > 0 && i < 15)begin
sum = q[i + 239] + q[i + 240] + q[i + 241] + q[i - 1] + q[i + 1] + q[i + 15] + q[i + 16] + q[i + 17];
end
else if(i > 240 && i < 255)begin
sum = q[i -17] + q[i - 16] + q[i - 15] + q[i - 1] + q[i + 1] + q[i - 241] + q[i - 240] + q[i - 239];
end
else if(i % 16 == 0)begin
sum = q[i -1] + q[i - 16] + q[i - 15] + q[i + 15] + q[i + 1] + q[i + 31] + q[i + 16] + q[i + 17];
end
else if(i % 16 == 15)begin
sum = q[i -17] + q[i - 16] + q[i - 31] + q[i - 1] + q[i - 15] + q[i + 15] + q[i + 16] + q[i + 1];
end
else begin
sum = q[i - 17] + q[i - 16] + q[i - 15] + q[i - 1] + q[i + 1] + q[i + 15] + q[i + 16] + q[i + 17];
end
case(sum)
4'd2:begin
q[i] <= q[i];
end
4'd3:begin
q[i] <= 1'b1;
end
default:begin
q[i] <= 1'b0;
end
endcase
end
end
end
endmodule