一、相邻点累加逻辑设计
所需软件
Verilog编程软件:Lattice Diamond(3.11.0.396.4_Diamond_x64)
Verilog仿真软件:ModelSim SE-64 10.2c(modelsim-win64-10.2c-se)
方法:用always语句块、组合逻辑实现相邻16点累加逻辑设计
符号图:
时序图:
Verilog代码:
Part1:Test13_sigma_16p.v文件(Verilog工程文件)
//2022-06-02
//相邻16点累加
//逻辑:对输入的信号进行补码运算,之后对得到的补码进行升位运算,升位之后再进行16点的相加,最后输出
//定义端口 时序逻辑:时钟,复位
module Test13_sigma_16p(
clk, //因为是时序逻辑,所有包含时钟clk和复位res
res,
data_in, //采样数据(输入的信号,为8位带符号位的原码)
syn_in, //采样时钟
data_out, //累加和(输出累加结果,为补码)
syn_out //累加和同步脉冲(为一个系统时钟周期宽度的脉冲)
);
//定义端口属性
input clk; //系统时钟(因为是时序逻辑,所以包含时钟clk和复位res)
input res;
input[7:0] data_in; //采样数据(输入的信号,为8位带符号位的原码),在采样时钟syn_in的上升沿变化
input syn_in; //采样时钟
output[11:0] data_out; //累加和(输出累加结果,为补码):data_in在相邻16点相加得到data_out,并由syn_out同步
output syn_out; //累加和同步脉冲(为一个系统时钟周期宽度的脉冲)
reg syn_in_n1; //采样时钟syn_in的反向延时
wire syn_pulse; //采样脉冲尖(用作采样时钟上升沿识别脉冲)
assign syn_pulse=syn_in&syn_in_n1; //采样脉冲尖:采样时钟syn_in和采样时钟的反向延时syn_in_n1的“与”
reg[3:0] con_syn; //采样时钟脉冲尖循环计数值(采样时钟循环计数器)
wire[7:0] comp_8; //输入的信号的补码
wire[11:0] d_12; //输入的信号的补码进行升位运算后的结果
//补码运算
assign comp_8=data_in[7]?{data_in[7],~data_in[6:0]+1}:data_in; //对输入的信号进行补码运算,补码运算值赋给comp_8
//升位运算:正数,前面扩展4个0;负数,前面扩展4个1;即对符号位的复制
assign d_12={comp_8[7],comp_8[7],comp_8[7],comp_8[7],comp_8}; //对输入的信号的补码comp_8进行升位运算
reg[11:0] sigma; //对输入的信号的补码进行升位运算后,对升位运算结果进行16点的累加计算
reg[11:0] data_out; //16点的累加计算的累加和(系统输出值)
reg syn_out; //累加和同步脉冲
//一旦定义了一个触发器,就需要对它复位
always@(posedge clk or negedge res)
if(~res) begin //复位信号下降沿,reg型变量清零
syn_in_n1<=0; //清零 采样时钟syn_in的反向延时syn_in_n1也需要进行复位
con_syn<=0; //清零 采样时钟循环计数器
sigma<=0;data_out<=0;
syn_out<=0;
end
else begin
syn_in_n1<=~syn_in; //syn_in_n1为采样时钟syn_in的反向延时
if(syn_pulse) begin //若采样脉冲尖syn_pulse为高电平(是脉冲尖)
con_syn<=con_syn+1; //则对循环计数脉冲尖con_syn进行计数(基于系统时钟的计数,但是在波形图上,计数基于采样脉冲尖)
end
if(syn_pulse) begin //若采样脉冲尖syn_pulse为高电平(是脉冲尖)
if(con_syn==15)begin //若循环计数脉冲尖con_syn(采样时钟循环计数器=)的个数达到15个
sigma<=d_12; //保留当前时刻输入信号(将输入的信号的补码进行升位运算的运算结果赋给sigma)
data_out<=sigma; //输出之前时钟计数15内输入信号累加结果(将输入的信号的补码进行升位运算的最终(累加15次)运算结果赋给系统输出变量data_out)
syn_out<=1; //将累加和同步脉冲syn_out置为高电平1
end
else begin
sigma<=sigma+d_12; //累和输入信号(对输入的信号的补码的升位运算值d_12进行累加计算)
end
end
else begin
syn_out<=0; //累加和同步脉冲syn_out为低电平0(使为高电平时的syn_out是一个尖、data_out一直保持)。
end
end
endmodule
Part2:Test13_sigma_16p_tb.v文件(Verilog仿真文件)
//2022-06-02
//相邻16点累加-testbench of Test13_sigma_16p
`timescale 1ns/10ps
module Test13_sigma_16p_tb;
//输入
reg clk_in,res_in;
reg[7:0] data_in;
reg syn_in;
//输出
wire[11:0] data_out;
wire syn_out;
Test13_sigma_16p Test13_sigma_16p(
.clk(clk_in), //因为是时序逻辑,所有包含时钟clk和复位res
.res(res_in),
.data_in(data_in), //采样数据(输入的信号)
.syn_in(syn_in), //采样时钟
.data_out(data_out), //累加和
.syn_out(syn_out) //累加和同步脉冲
);
//验证方法:让输入信号连续等于正1或连续等于负1,看是否能加出来正16或负16
initial begin
clk_in<=0;res_in<=0;
data_in<=1; //令输入信号为正1 //data_in:采样信号,设定其一直为1
// data_in<=8'b1000_0001; //令输入信号为负1
syn_in<=0;
#17 res_in<=1;
#25000 $stop; //16点一个周期,10ns一个点,160ns一个周期,500ns够
end
always #5 clk_in<=~clk_in; //设置系统时钟,时钟周期为10ns
always #100 syn_in<=~syn_in; //设置采样时钟,时钟周期为200ns
endmodule
仿真波形:
1、令输入信号为持续的正1,可得到累加得到正16
2、令输入信号为持续的负1,可得到累加得到负16
注意事项
1、相邻16点累加逻辑:对输入的信号进行补码运算,之后对得到的补码进行升位运算,升位之后再进行相邻的16点的累加求和并输出;
2、8位升12位的升位运算方法:正数,前面扩展4个0;负数,前面扩展4个1;即对符号位的复制;
3、相邻16点累加逻辑的验证方法:让输入信号连续等于正1或连续等于负1,看是否能加出来正16或负16;
4、在相邻16点累加逻辑的测试代码中,勿忘记既需要设置系统时钟,又需要设置采样时钟;
5、8位二进制的负1可表示为:8'b1000_0001;8位二进制的正1可表示为:1、8'b0000_0001。