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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部