IC笔试牛客网verilog刷题总结
1.四选一多路选择器
sel 00:d3,01:d2,10:d1,11:d0
注:always 中beign end中必须是reg类型
assign 将reg类型数据赋给wire类型
`timescale 1ns/1ns
module mux4_1(
input [1:0]d1,d2,d3,d0,
input [1:0]sel,
output[1:0]mux_out
);
//*************code***********//reg[1:0]mux_out_reg;always@(*)begincase(sel)2'b00:mux_out_reg=d3;2'b01:mux_out_reg=d2;2'b10:mux_out_reg=d1;2'b11:mux_out_reg=d0;endcaseendassign mux_out = mux_out_reg;//*************code***********//endmodule
2.异步复位的串联T触发器
异步复位必须为边沿触发,题中rst为低有效,所以为下降沿检测 rst_n
T触发器,输入为1,输出取反,输入为0,输出保持
`timescale 1ns/1ns
module Tff_2 (
input wire data, clk, rst,
output reg q
);
//*************code***********//reg q1;always@(posedge clk or negedge rst)beginif(~rst)beginq1<=0;q<=0;endelse beginif(data)q1<=!q1;elseq1<=q1;if(q1)q<=!q;elseq<=q;endend//*************code***********//
endmodule
3.奇偶校验
单目运算符(| ^ &)
a=4‘b1010
- c=&a; 检测是否全为1 全为1,c=1’b1
- c=^a; 奇偶校验(检测1的个数是奇数还是偶数) 奇数个1,c=1’b1
- c=|a; 检测是否全为0 全为0,c=1’b1
`timescale 1ns/1ns
module odd_sel(
input [31:0] bus,
input sel,
output check
);
//*************code***********//
assign check = sel ? ^bus:~^bus;//*************code***********//
endmodule
4.移位运算与乘法
移位运算符(<<>>)
移位可以实现无符号数的乘除法,有符号数的乘法
>>高位补零只能是无符号数的除法
- a=4‘b0010
- c=a<<1=4'b0100;
- c=a>>1=4'b0001;
拼接运算符{ }
- a=1'b1;
- c=3'b101;
- d={a,c}=4'b1101;
- d={1'b0,a}=2'b01;
- d={2{a}}=2'b11;
- d={a,b[1:0]}=3'101;
`timescale 1ns/1ns
module multi_sel(
input [7:0]d ,
input clk,
input rst,
output reg input_grant,
output reg [10:0]out
);
//*************code***********//reg [1:0]cnt;reg [7:0]din;always@(posedge clk or negedge rst)beginif(!rst)begincnt <= 0;out <= 0;input_grant <= 0;din <= 0;endelse begincnt <= cnt+1;case(cnt)0:begindin <= d;input_grant <= 1;out <= d;end1:begininput_grant <= 0;out <= (din<<2)-din;end2:begininput_grant <= 0;out <= (din<<3)-din;end3:begininput_grant <= 0;out <= (din<<3);enddefault: begininput_grant <= 0;out <= d;endendcaseendend//*************code***********//
endmodule
5.位拆分与运算
`timescale 1ns/1nsmodule data_cal(
input clk,
input rst,
input [15:0]d,
input [1:0]sel,output reg[4:0]out,
output reg validout
);
//*************code***********//reg [15:0] data_lock;always@(posedge clk or negedge rst) beginif(!rst)data_lock <= 0;else if(!sel)data_lock <= d;endalways@(posedge clk or negedge rst) beginif(!rst)beginout <= 0;validout <= 0;endelse begincase(sel)0:beginout <= 'b0;validout <= 0;end1:beginout <= data_lock[3:0]+data_lock[7:4];validout <= 1;end2:beginout <= data_lock[3:0]+data_lock[11:8];validout <= 1;end3:beginout <= data_lock[3:0]+data_lock[15:12];validout <= 1;enddefalut:beginout <='b0;validout <= 0;endendcaseendend//*************code***********//
endmodule
6.多功能数据处理器
signed声明为有符号数
`timescale 1ns/1ns
module data_select(input clk,input rst_n,input signed[7:0]a,input signed[7:0]b,input [1:0]select,output reg signed [8:0]c
);always@(posedge clk or negedge rst_n)beginif(!rst_n)beginc <= 0;endelse begincase(select)2'b00: c <= a;2'b01: c <= b;2'b10: c <= a+b;2'b11: c <= a-b;default: c<= 0;endcaseendend
endmodule
7.求两个数的差值
`timescale 1ns/1ns
module data_minus(input clk,input rst_n,input [7:0]a,input [7:0]b,output reg [8:0]c
);always@(posedge clk or negedge rst_n)beginif(!rst_n)beginc <= 0;endelse if(a > b)c <= a-b;elsec <= b-a;end
endmodule
8.使用generate…for语句简化代码
循环变量必须使用genvar声明
在generate...for中使用begin end 必须后面接名称,并行运行
for循环一般在always块中使用,使用begin end 不用接名字
`timescale 1ns/1ns
module gen_for_module( input [7:0] data_in,output [7:0] data_out
);genvar i;generatefor(i=0;i<8;i=i+1)begin : bit_reverseassign data_out[i] = data_in[7-i];endendgenerateendmodule
9.使用子模块实现三输入数的大小比较
模块调用:模块名称 起的新名字(
.clk原模块引脚名 (现在引入引脚的名字));
`timescale 1ns/1ns
module main_mod(input clk,input rst_n,input [7:0]a,input [7:0]b,input [7:0]c,output [7:0]d
);wire [7:0]m,n;sub_mod mod_ab(.clk(clk),.rst_n(rst_n),.data_a(a),.data_b(b),.data_c(m)
);sub_mod mod_bc(.clk(clk),.rst_n(rst_n),.data_a(a),.data_b(c),.data_c(n)
);sub_mod mod_mn(.clk(clk),.rst_n(rst_n),.data_a(m),.data_b(n),.data_c(d)
);
endmodule
module sub_mod(input clk,input rst_n,input[7:0]data_a,input[7:0]data_b,output reg [7:0]data_c
);always@(posedge clk or negedge rst_n)if(!rst_n)data_c <= 0;else if(data_a > data_b)data_c <= data_b;elsedata_c <= data_a;endmodule
10.使用函数实现数据大小端转换
function和task
- 消耗仿真时间与否,task可以有消耗仿真时间的语句,function不能有消耗时间的语句,task不一定就消耗仿真时间。
- task可以调用function,function不能调用task。
- 在verilog中:task可以返回多个值(output),function只能返回一个值
- task是没有return的, void function也是没有return
- function通常用于计算,或描述组合逻辑,函数名返回一个结果,可调用其他函数
- function至少有一个输入变量,函数有一个返回值,缺省时默认返回1bit的reg寄存器类型数据
`timescale 1ns/1ns
module function_mod(input clk,input rst_n,input [3:0]a,input [3:0]b,output [3:0]c,output [3:0]d);function [3:0] data_rev;input [3:0] data_in;begindata_rev[0] = data_in[3];data_rev[1] = data_in[2];data_rev[2] = data_in[1];data_rev[3] = data_in[0];endendfunctionassign c = data_rev(a);assign d = data_rev(b);endmodule
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
