1.Function内部不能使用时间延迟,也不能使用@这种事件触发,只能实现一些组合逻辑运算,也不能调用task。
task可以有时间延迟,function不可以用时间延迟。
Verilog 中的 task 是一种不可综合的语法,它既提供了从不同位置执行公共过程的能力(因为这样可以实现代码共享),也提供了把大过程切分成小过程的能力(因为小过程更便于阅读和调试)。相较于 function, task 的 input 和 output 是可选项,同时其中也可以包含延迟控制语句,常被用在 testbench 中。
2.以下不是串行总线的是:
A、SDIO
B、SPI
C、IIS
D、AHB
SDIO用于SD卡接口传输总线,CMD、4bitdata clk串行的;
SPI用于adc、dac读出写入接口或者一些芯片控制寄存器接口,或者SPI flash分为3线制和4线制,sdi sdo cs clk
IIS用于传输音频,比如一些音频DAC都是IIS接口用于适配各种采样率音频和左右声道数据。
AHB,ARM公司的AMBA总线的一部分主要CPU和外设DMA, 内存通信的总线,具 有32bit位宽,地址总线构成的,并行总线。
CRC校验
4、看图编程
`timescale 1ns/1ps
module shift_t(
input wire clk,
input wire rst_n,
output wire pi
);
reg [8:0] shift_reg;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
shift_reg<=9'b11111_1111;
end
else begin
shift_reg<={shift_reg[7:0],shift_reg[4]^shift_reg[8]};
end
end
assign pi=shift_reg[6];
endmodule
5、打两拍同步
题目分析:
1.模块名称 rise_det
2.时钟上升沿触发
3.复位低有效并且异步复位
4.检测输入in data的上升沿,之后两周周期后拉高一个时钟周期
module rise_det(
input wire clk,
input wire rst_n,
input wire in_data,
output wire out_data
);
reg indata_dly1,indata_dly2;
reg out_det_reg;
always @(posedge clk or negedge rst_n)begin //这是异步复位,仅有clk是同步复位
if(!rst_n)begin
indata_dly1<=1'b0;
indata_dly2<=1'b0;
end
else begin
indata_dly1<=in_data;
indata_dly2<=indata_dly1;
end
end
always @(posedge clk or negedge rst_n)begin //这是异步复位,仅有clk是同步复位
if(!rst_n)begin
out_det_reg<=1'b0;
end
else if(indata_dly1==1'b1 && indata_dly2==1'b0) begin
out_det_reg<=1'b1;
end
else begin
out_det_reg<=1'b0;
end
end
assign out_data=out_det_reg;
endmodule
//测试文件
`timescale 1ns/1ns
module tb_rise_det(); //测试模块
parameter T=20;
reg sys_clk;
reg sys_rst_n;
reg in_data;
wire out_data;
always #(T/2) sys_clk=~sys_clk;
initial begin
sys_clk=1'b0;
sys_rst_n=1'b0;
#(T+1)
sys_rst_n=1'b1;
end
initial begin
in_data=0;
#1000
in_data=1;
#100
in_data=0;
#1000
in_data=1;
#100
in_data=0;
end
rise_det u_rise_det(
.clk (sys_clk),
.rst_n (sys_rst_n),
.in_data (in_data),
.out_data (out_data)
);
endmodule
6、异步FIFO
module sfifo_16×16(
input wire clk,
input wire rst_n,
input wire write,
input wire [15:0] data_in,
input wire read,
output wire [15:0] data_out,
output wire full,
output wire empty
);
reg [15:0] BRAM_16×16[15:0];
reg [4:0] wraddr,rdaddr;
reg [15:0] tmp_rdata;
//写地址递增
always @(posedge clk)begin
if(rst_n==1'b1)begin
wraddr <= 1'b0;
end
else if (write==1'b1)begin
wraddr <= wraddr + 1'b1;
end
end
//读地址递增
always @(posedge clk)begin
if(rst_n==1'b1)begin
rdaddr <= 1'b0;
end
else if (read==1'b1)begin
rdaddr <= rdaddr + 1'b1;
end
end
//写数据
always @(posedge clk)begin
if(write==1'b1)begin
BRAM_16×16[wraddr] <= data_in;
end
end
//1 clk latency
always @(posedge clk)begin
tmp_rdata <= BRAM_16×16[rdaddr];
end
//读数据
assign data_out <= tmp_rdata;
//判断读空、写满
assign empty = (wraddr == rdaddr)?1'b1:1'b0;
assign full = (~{wraddr[4],wraddr[3:0]} == rdaddr)?1'b1:1'b0;
endmodule
//测试文件
//测试文件
`timescale 1ns/1ns
module tb_sfifo_16×16(); //测试模块
reg clk;
reg write;
reg read;
reg rst;
reg [15:0] data_in;
wire [15:0] data_out;
wire full;
wire empty;
initial begin
rst = 1;
repeat(10)@(posedge clk);
rst = 0;
repeat(10)@(posedge clk);
drive_w();
repeat(10)@(posedge clk);
drive_r();
end
task drive_w;
begin
integer it;
for(it=0;it<16;it=it+1)begin
write <= 1;
data_in <= it[15:0];
@(posedge clk);
end
write <= 1'b0;
end
endtask
task drive_r;
begin
integer it;
for(it=0;it<16;it=it+1)begin
read <= 1;
@(posedge clk);
end
read <= 1'b0;
end
endtask
sfifo_16×16 u_sfifo_16×16(
.clk (clk),
.rst_n (rst),
.write (write),
.data_in (data_in),
.read (read),
.data_out (data_out),
.full (full),
.empty (empty)
);
endmodule