sigma_16p.v:
//2022-1-22 Verilog学习
// 相邻16点相加
`timescale 1ns/10ps
// 定义端口 时序逻辑:时钟,复位
module sigma_16p(
clk,
res,
data_in,
syn_in, // 采样时钟
data_out,
syn_out
);
// 定义端口属性
input clk;
input res;
input[7:0] data_in; // 采样信号
input syn_in; // 采样时钟
output[11:0] data_out; // 累加结果输出
output syn_out; // 累加结果同步脉冲
reg syn_in_n1; // syn_in的反向延时 寄存器
wire syn_pulse; // 采样时钟上升沿识别脉冲
assign syn_pulse = 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; // 补码运算
// 升位运算:正数,前面扩展4个0 负数,前面扩展4个1,即符号位的复制
assign d_12 = {comp_8[7],comp_8[7],comp_8[7],comp_8[7], comp_8}; // 升位
reg[11:0] sigma; // 累加计算
reg[11:0] data_out;
reg syn_out;
always@(posedge clk or negedge res)
if(~res)begin // 复位信号下降沿 reg型变量清零
syn_in_n1 <= 0; // 清零 采样时钟的反向延时
con_syn <= 0; // 清零 采样时钟循环计数器
sigma <= 0;
data_out <= 0;
syn_out <= 0;
end
else begin
syn_in_n1 <= ~syn_in_n1; // 采样时钟的反向延时
if(syn_pulse)begin
con_syn = con_syn+1;
end
if(syn_pulse)begin
if(con_syn==15)begin // 采样时钟循环计数器=15
sigma <= d_12; // 保留当前时刻输入信号
data_out <= sigma; // 输出之前时钟计数15内输入信号累加结果
syn_out<=1;
end
else begin
sigma <= sigma + d_12; // 累和输入信号
end
end
else begin
syn_out <= 0;
end
end
endmodule
// testbench 测试台
module sigma_16p_tb;
// 输入
reg clk,res;
reg[7:0] data_in;
reg syn_in;
// 输出
wire[11:0] data_out;
wire syn_out;
sigma_16p sigma_16p(
.clk(clk),
.res(res),
.data_in(data_in),
.syn_in(syn_in),
.data_out(data_out),
.syn_out(syn_out)
);
initial begin
clk<=0; res<=0; data_in=1;syn_in<=0; // 8'b1000_0001:-1
#17 res<=1;
#25000 $stop; // 16点一个周期,10ns一个点,160ns一个周期,500ns够
end
always #5 clk = ~clk; // 系统时钟
always #100 syn_in <= ~syn_in; // 采样时钟
endmodule
modelsim:
为什么有14???