verilog编程题
文章目录
- verilog编程题
- 序列检测电路(状态机实现)
- 分频电路
- 计数器
- 译码器
- 选择器
- 加减器
- 触发器
- 寄存器
序列检测电路(状态机实现)
module Detect_101(
input clk,
input rst_n,
input data,
output flag_101
);
parameter S0 = 0,
S1 = 1,
S2 = 2,
S3 = 3;
reg [1:0] state;
always @(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)begin
state <= S0;
end
else begin
case(state)
S0:
if(data == 1)
state <= S1;
else
state <= S0;
S1:
if(data == 0)
state <= S2;
else
state <= S1;
S2:
if(data == 1)
state <= S3;
else
state <= S0;
S3:
if(data == 1)
state <= S1;
else
state <= S2;
default:
state <=S0;
endcase
end
end
assign flag_101 = (state == S3)? 1'b1: 1'b0;
endmodule
分频电路
采用触发器反向输出端连接到输入端的方式,可构成简单的 2 分频电路。
以此为基础进行级联,可构成 4 分频,8 分频电路。
按题目要求,几分频就留哪个。
module even_divisor
# (parameter DIV_CLK = 10 )
(
input rstn ,
input clk,
output clk_div2,
output clk_div4,
output clk_div10
);
//2 分频
reg clk_div2_r ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
clk_div2_r <= 'b0 ;
end
else begin
clk_div2_r <= ~clk_div2_r ;
end
end
assign clk_div2 = clk_div2_r ;
//4 分频
reg clk_div4_r ;
always @(posedge clk_div2 or negedge rstn) begin
if (!rstn) begin
clk_div4_r <= 'b0 ;
end
else begin
clk_div4_r <= ~clk_div4_r ;
end
end
assign clk_div4 = clk_div4_r ;
//N/2 计数
reg [3:0] cnt ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
cnt <= 'b0 ;
end
else if (cnt == (DIV_CLK/2)-1) begin
cnt <= 'b0 ;
end
else begin
cnt <= cnt + 1'b1 ;
end
end
//输出时钟
reg clk_div10_r ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
clk_div10_r <= 1'b0 ;
end
else if (cnt == (DIV_CLK/2)-1 ) begin
clk_div10_r <= ~clk_div10_r ;
end
end
assign clk_div10 = clk_div10_r ;
endmodule
计数器
module Count
(
input clk ,
input rst_n ,
output reg [ 3:0] cnt
);
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt <= 4'd0;
else if(cnt==4'd9)
cnt <= 4'd0;
else
cnt <= cnt + 1'b1;
end
endmodule
译码器
`timescale 10ns/1ns
module decode3_8 (data_out,data_in,enable) ;
input [2:0] data_in;
input enable;
output [7:0] data_out;
reg [7:0] data_out;
always @(data_in or enable)
begin
if (enable==1)
case (data_in )
3'b000: data_out=8'b11111110;
3'b001: data_out=8'b11111101;
3'b010: data_out=8'b11111011;
3'b011: data_out=8'b11110111;
3'b100: data_out=8'b11101111;
3'b101: data_out=8'b11011111;
3'b110: data_out=8'b10111111;
3'b111: data_out=8'b01111111;
default: data_out=8'bxxxxxxxx;
endcase
else
data_out=8'b11111111;
end
endmodule
选择器
代码为4选1,如果题目是2选1或者更多选1就case后进行更改
module mux_4_1 (
input C, D, E, F,
input [1:0] S,
output reg Mux_out
);
always @ (C or D or E or F or S) begin
case(S)
2'b00 : Mux_out = C;
2'b01 : Mux_out = D;
2'b10 : Mux_out = E;
default : Mux_out = F;
endcase
end
endmodule
加减器
16位加减法器。当sub为1时,是减法;当sub为0时是加法。
看题目要求,有几位写几位
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0]sum
);
wire [31:0]xor_1;
wire [15:0]sum_1;
wire [15:0]sum_2;
wire cout_1,cout_2;
//xor xor_gate(xor_1,b,sub);//逻辑或,我们这里的设计不应该是逻辑或,应该是下边的按位取或
assign xor_1 = b^{32{sub}} ;//按位异或
assign sum = {sum_2,sum_1};
add16 u1_add16(
.a(a[15:0]),
.b(xor_1[15:0]),
.cin(sub),
.sum(sum_1),
.cout(cout_1)
);
add16 u2_add16(
.a(a[31:16]),
.b(xor_1[31:16]),
.cin(cout_1),
.sum(sum_2),
.cout(cout_2)
);
endmodule
触发器
带同步清0、同步置1的D触发器
module D_EF(q,qn,d,clk,set,reset)
input d,clk,set,reset;
output q,qn;
reg q,qn;
always @ (posedge clk)
begin
if(reset) begin q<=0;qn<=1;end//同步清0,高有效
else if(set) begin q<=1;qn<=1;end //同步置1,高有效
else begin q<=~d;qn<=~d;end
end
endmodule
寄存器
有异步清零端的n位寄存器,看题目要求,有几位n就写几
module regn(D,clk,reset,Q);
parameter n=16;
input [n-1] D;
input clk,reset;
output [n-1] reg Q;
always @(negedge reset,posedge clk)
if(!reset) //复位端reset低电平有效
Q<=0;
else
Q<=D;
endmodule