Verilog逻辑设计学习4

Posted on 2023-01-24 20:15  _Chapman  阅读(167)  评论(0编辑  收藏  举报

边沿捕抓电路

边沿捕抓指的是一个信号的上升或者下降沿被检测出来。如果输入信号出现一个上升沿或者下降沿,这个电路可以输出对应的信号。

下降沿捕抓电路

这个电路是检测信号下降沿用的电路。在Verilog里面实现可以通过以下语句实现:

module degedown_test(
input sys_clk,
input sys_rst_n,
input A,
output B
);
reg in0;
reg in1;

assign B = in1 & (~in0);//下降沿识别语句,如果下降沿出现,输出1。

always @(posedge sys_clk or negedge sys_rst_n)begin
if (!sys_rst_n) begin //复位成立,寄存器复位清零
in0 <= 1b'0;
in1 <= 1b'0;
end

else begin //给寄存器统一赋状态值
in0 <= A;
in1 <= in0;
end

end

endmodule

上升沿捕抓电路

这个电路是检测信号上升沿用的电路。在Verilog里面实现可以通过以下语句实现:

module degehigh_test(
input sys_clk,
input sys_rst_n,
input A,
output B
);
reg in0;
reg in1;

assign B = (~in1)&in0;//上升沿识别语句,如果上升沿出现,输出1。

always @(posedge sys_clk or negedge sys_rst_n)begin
if (!sys_rst_n) begin //复位成立,寄存器复位清零
in0 <= 1b'0;
in1 <= 1b'0;
end

else begin //给寄存器统一赋状态值
in0 <= A;
in1 <= in0;
end

end

endmodule

寄存器移位电路

在寄存器中数据实现左移或者右移的电路。下面以寄存器左移一位在Verilog里面实现为例子:

module tran_test(
input sys_clk,
input sys_rst_n,
output A
);
reg [3:0] in0;

always @(posedge sys_clk or negedge sys_rst_n)begin
if (!sys_rst_n) begin //复位成立,寄存器复位
in0 <= 4b'1;
end

else begin //不停把最高位放到最低位
in0 <= {in0[2:0],in0[3]};
in1 <= in0;
end

end

endmodule

上述例子是:把0001里面,最高位放到最低位。则由0001变成0010,如此类推,下一次循环变成0100,再变成1000,最后变回0001,为一个循环。

整数倍位宽转换电路

如果一个电路的数据宽度是8位,可是这个电路后续的电路数据位宽是16位。这个时候就需要整数倍位宽转换电路。这个电路工作原理和上一个陈述的寄存器数据左右移电路的工作原理有点相类似,都是对寄存器的数据进行操作。

module tran_test(
input sys_clk,
input sys_rst_n,
input [7:0] A, //输入为8位数据
output reg [15:0] B //输出寄存器
);
reg [7:0] in0;
reg [7:0] in1;

always @(posedge sys_clk or negedge sys_rst_n)begin
if (!sys_rst_n) begin //复位成立,寄存器复位
in0 <= 8b'0;
in1 <= 8b'0;
end

else begin //不停把数据向更深层寄存器推
in0 <= A;
in1 <= in0;
end

end

//将两个寄存器的数据合并成16位数据输出
assign B = {in1[7:0],in0[7:0]};

endmodule

非整数倍位宽转换电路

如果一个电路的数据宽度是8位,可是这个电路后续的电路数据位宽是12位。这个时候就需要非整数倍位宽转换电路。这个电路工作原理和整数倍位宽转换电路的工作原理有点相类似,都是对寄存器的数据进行操作。

module tran_test(
input sys_clk,
input sys_rst_n,
input [7:0] A, //输入为8位数据
output reg [11:0] B //输出寄存器
);
reg [7:0] in0;
reg [7:0] in1;
reg [1:0] time;

always @(posedge sys_clk or negedge sys_rst_n)begin
if (!sys_rst_n)//复位后寄存器清零
time <= 2'b0;
else
time <= time + 1'b0;

end

always @(posedge sys_clk or negedge sys_rst_n)begin
if (!sys_rst_n) begin //复位成立,寄存器复位
in0 <= 8b'0;
in1 <= 8b'0;
end
else begin //不停把数据向更深层寄存器推
in0 <= A;
in1 <= in0;
end

end

always @(posedge sys_clk or negedge sys_rst_n)begin
if (!sys_rst_n) //复位成立,寄存器复位
A <= 12'b0;
else begin //不停把数据向更深层寄存器推
if(time == 2'b01)
A <= {in1[7:0],in0[7:4]};
else if(time == 2'b10)
A <= {in1[3:0],in2[7:0]]};
time <= 2'b0;
else
A <= A;
end

end

endmodule
这样把前一个数据和后一个数据的一半组成一个新的数据。这样就实现了数据位宽的转换电路。