目录
(2)代码
VL1:4选1多路选择器
(1)描述
制作一个四选一的多路选择器,要求输出定义上为线网类型
状态转换:
d0 11
d1 10
d2 01
d3 00
信号示意图:
波形示意图:
输入描述:
输入信号 d1,d2,d3,d4 sel
类型 wire
输出描述:
输出信号 mux_out
类型 wire
(2)代码
`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_ff ;
wire [1:0] mux_out ;
always @(*) begin
case(sel[1:0])
2'b00 : mux_out_ff = d3 ;
2'b01 : mux_out_ff = d2 ;
2'b10 : mux_out_ff = d1 ;
default : mux_out_ff = d0 ;
endcase
end
assign mux_out = mux_out_ff ;
//*************code***********//
endmodule
VL2:异步复位的串联T触发器
(1)描述
用verilog实现两个串联的异步复位的T触发器的逻辑,结构如图:
信号示意图:
波形示意图:
输入描述:
输入信号 data, clk, rst
类型 wire
在testbench中,clk为周期5ns的时钟,rst为低电平复位
输出描述:
输出信号 q
类型 reg
(2)代码
`timescale 1ns/1ns
module Tff_2 (
input wire data, clk, rst,
output reg q
);
//*************code***********//
reg q_0 ;
always @(posedge clk or negedge rst) begin
if(!rst)
q_0 <= 1'b0 ;
else begin
if(data == 1'b0)
q_0 <= q_0 ;
else
q_0 <= ~q_0 ;
end
end
always @(posedge clk or negedge rst) begin
if(!rst)
q <= 1'b0 ;
else begin
if(q_0 == 1'b0)
q <= q ;
else
q <= ~q ;
end
end
//*************code***********//
endmodule
VL3:奇偶校验
(1)描述
题目描述:
现在需要对输入的32位数据进行奇偶校验,根据sel输出校验结果(1输出奇校验,0输出偶校验)
信号示意图:
波形示意图:
输入描述:
输入信号 bus sel
类型 wire
输出描述
输出信号 check
类型 wire
(2)代码
`timescale 1ns/1ns
module odd_sel(
input [31:0] bus,
input sel,
output check
);
//*************code***********//
wire check ;
wire check_odd ;
wire check_even ;
assign check_odd = ^bus ;
assign check_even = ~check_odd ;
assign check = sel ? check_odd : check_even ;
//*************code***********//
endmodule
VL4:移位运算与乘法
(1)描述
题目描述:
已知d为一个8位数,请在每个时钟周期分别输出该数乘1/3/7/8,并输出一个信号通知此时刻输入的d有效(d给出的信号的上升沿表示写入有效)
信号示意图:
波形示意图:
输入描述:
输入信号 d, clk, rst
类型 wire
在testbench中,clk为周期5ns的时钟,rst为低电平复位
输出描述
输出信号 input_grant out
类型 reg
(2)代码
`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 [43 : 0] shift_register ;
reg [2 : 0] cnt ;
always @(posedge clk or negedge rst) begin
if(!rst)
shift_register <= 44'h0 ;
else begin
shift_register[10:0] <= {3'h0, d[7:0]} ; // d*1
shift_register[21:11] <= shift_register[10:0] * 2'd3 ; // d*3
shift_register[32:22] <= (shift_register[21:11] / 2'd3) * 3'd7 ; // d*7
shift_register[43:33] <= (shift_register[32:22] / 3'd7) * 4'd8 ; // d*8
end
end
always @(posedge clk or negedge rst) begin
if(!rst)
cnt <= 3'h0 ;
else begin
if(cnt == 3'd4)
cnt <= 3'h1 ;
else
cnt <= cnt + 1'b1 ;
end
end
always @(*) begin
if(cnt == 3'd1)
input_grant = 1'b1 ;
else
input_grant = 1'b0 ;
end
always @(*) begin
case(cnt)
3'b00 : out = 11'h0 ;
3'b01 : out = shift_register[10:0] ;
3'b10 : out = shift_register[21:11] ;
3'b11 : out = shift_register[32:22] ;
default : out = shift_register[43:33] ;
endcase
end
//*************code***********//
endmodule
VL5:位拆分与运算
(1)描述
题目描述:
现在输入了一个压缩的16位数据,其实际上包含了四个数据[3:0][7:4][11:8][15:12],
现在请按照sel选择输出四个数据的相加结果,并输出valid_out信号(在不输出时候拉低)
0: 不输出且只有此时的输入有效
1:输出[3:0]+[7:4]
2:输出[3:0]+[11:8]
3:输出[3:0]+[15:12]
信号示意图:
波形示意图:
输入描述:
输入信号 d, clk, rst
类型 wire
在testbench中,clk为周期5ns的时钟,rst为低电平复位
输出描述
输出信号 validout out
类型 reg
(2)代码
`timescale 1ns/1ns
module data_cal(
input clk,
input rst,
input [15:0]d,
input [1:0]sel,
output [4:0]out,
output validout
);
//*************code***********//
reg [15 : 0] d_real ;
reg [4 : 0] out_ff ;
always @(posedge clk or negedge rst) begin
if(!rst)
d_real <= 16'd0 ;
else if(sel == 2'd0)
d_real <= d ;
end
always @(*) begin
case(sel)
2'd0 : out_ff = 5'h0 ;
2'd1 : out_ff = {1'b0, d_real[3:0]} + {1'b0, d_real[7 : 4]} ;
2'd2 : out_ff = {1'b0, d_real[3:0]} + {1'b0, d_real[11: 8]} ;
default : out_ff = {1'b0, d_real[3:0]} + {1'b0, d_real[15:12]} ;
endcase
end
assign out = out_ff ;
assign validout = (sel == 2'd0) ? 1'b0 : 1'b1;
//*************code***********//
endmodule
VL6:多功能数据处理器
(1)描述
题目描述:
根据指示信号select的不同,对输入信号a,b实现不同的运算。输入信号a,b为8bit有符号数,当select信号为0,输出a;当select信号为1,输出b;当select信号为2,输出a+b;当select信号为3,输出a-b.
信号示意图:
输入描述:
clk:系统时钟
rst_n:复位信号,低电平有效
a,b:8bit位宽的有符号数
select:2bit位宽的无符号数
输出描述
c:9bit位宽的有符号数
(2)代码
`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
);
wire [8:0] a_ext ;
wire [8:0] b_ext ;
assign a_ext = {a[7], a[7:0]} ;
assign b_ext = {b[7], b[7:0]} ;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
c <= 9'h0 ;
else begin
case(select)
2'd0 : c <= a_ext ;
2'd1 : c <= b_ext ;
2'd2 : c <= a_ext + b_ext ;
default : c <= a_ext - b_ext ;
endcase
end
end
endmodule
VL7:求两个数的差值
(1)描述
题目描述:
根据输入信号a,b的大小关系,求解两个数的差值:输入信号a,b为8bit位宽的无符号数。如果a>b,则输出a-b,如果a≤b,则输出b-a。
信号示意图:
输入描述:
clk:系统时钟
rst_n:复位信号,低电平有效
a,b:8bit位宽的无符号数
输出描述
c:8bit位宽的无符号数
(2)代码
`timescale 1ns/1ns
module data_minus(
input clk,
input rst_n,
input [7:0]a,
input [7:0]b,
output reg [8:0]c
);
wire [8:0] a_ext ;
wire [8:0] b_ext ;
assign a_ext = { 1'b0, a[7:0] } ;
assign b_ext = { 1'b0, b[7:0] } ;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
c <= 9'h0 ;
else begin
if(a_ext > b_ext)
c <= a_ext - b_ext ;
else
c <= b_ext - a_ext ;
end
end
endmodule
VL8:使用generate…for语句简化代码
(1)描述
题目描述:
在某个module中包含了很多相似的连续赋值语句,请使用generata…for语句编写代码,替代该语句,要求不能改变原module的功能。
使用Verilog HDL实现以上功能并编写testbench验证。
module template_module(
input [7:0] data_in,
output [7:0] data_out
);
assign data_out [0] = data_in [7];
assign data_out [1] = data_in [6];
assign data_out [2] = data_in [5];
assign data_out [3] = data_in [4];
assign data_out [4] = data_in [3];
assign data_out [5] = data_in [2];
assign data_out [6] = data_in [1];
assign data_out [7] = data_in [0];
endmodule
输入描述:
data_in:8bit位宽的无符号数
输出描述
data_out:8bit位宽的无符号数
(2)代码
`timescale 1ns/1ns
module gen_for_module(
input [7:0] data_in,
output [7:0] data_out
);
genvar i;
generate
for(i=0; i<8; i=i+1) begin : gen_data
assign data_out[i] = data_in[7-i];
end
endgenerate
endmodule
VL9:使用子模块实现三输入数的大小比较
(1)描述
题目描述:
在数字芯片设计中,通常把完成特定功能且相对独立的代码编写成子模块,在需要的时候再在主模块中例化使用,以提高代码的可复用性和设计的层次性,方便后续的修改。
请编写一个子模块,将输入两个8bit位宽的变量data_a,data_b,并输出data_a,data_b之中较小的数。并在主模块中例化,实现输出三个8bit输入信号的最小值的功能。
子模块的信号接口图如下:
主模块的信号接口图如下:
输入描述:
clk:系统时钟
rst_n:异步复位信号,低电平有效
a,b,c:8bit位宽的无符号数
输出描述
d:8bit位宽的无符号数,表示a,b,c中的最小值
(2)代码
`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] min_ab ;
reg [7:0] c_d1 ;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
c_d1 <= 8'h0 ;
else
c_d1 <= c ;
end
sub_mod u_sub_mod0(
//Input
.clk (clk ) ,
.rst_n (rst_n ) ,
.a (a ) ,
.b (b ) ,
//Output
.c (min_ab)
);
sub_mod u_sub_mod1(
//Input
.clk (clk ) ,
.rst_n (rst_n ) ,
.a (min_ab) ,
.b (c_d1 ) ,
//Output
.c (d )
);
endmodule
module sub_mod(
input clk,
input rst_n,
input [7:0]a,
input [7:0]b,
output [7:0]c
);
reg [7:0] c_ff ;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
c_ff <= 8'h0 ;
else begin
if(a <= b)
c_ff <= a ;
else
c_ff <= b ;
end
end
assign c = c_ff ;
endmodule
VL10:使用函数实现数据大小端转换
(1)描述
题目描述:
在数字芯片设计中,经常把实现特定功能的模块编写成函数,在需要的时候再在主模块中调用,以提高代码的复用性和提高设计的层次,分别后续的修改。
请用函数实现一个4bit数据大小端转换的功能。实现对两个不同的输入分别转换并输出。
信号示意图:
输入描述:
clk:系统时钟
rst_n:异步复位信号,低电平有效
a,b:4bit位宽的无符号数
输出描述
c,d:8bit位宽的无符号数
(2)代码
`timescale 1ns/1ns
module function_mod(
input [3:0]a,
input [3:0]b,
output [3:0]c,
output [3:0]d
);
function [3:0] little_big_endian_converter;
input [3:0] in ;
begin
little_big_endian_converter[0] = in[3] ;
little_big_endian_converter[1] = in[2] ;
little_big_endian_converter[2] = in[1] ;
little_big_endian_converter[3] = in[0] ;
end
endfunction
assign c = little_big_endian_converter(a) ;
assign d = little_big_endian_converter(b) ;
endmodule