【牛客】1 基础语法
VL1 四选一多路器
`timescale 1ns/1ns module mux4_1( input [1:0]d1,d2,d3,d0, input [1:0]sel, output [1:0]mux_out ); //*************code***********// assign mux_out = (sel==0)?d3: ((sel==1)?d2: ((sel==2)?d1: d0)); //*************code***********// endmodule
VL2 异步复位的串联T触发器
题目已经提示了是两个串联的T触发器,只要记得T触发器在输入高电平时,输出翻转即可。
`timescale 1ns/1ns module Tff_2 ( input wire data, clk, rst, output reg q ); //*************code***********// reg q_r; always@(posedge clk or negedge rst) begin if(~rst) begin q_r <= 1'b0; q <= 1'b0; end else begin if(data) q_r <= ~ q_r; if(q_r) q <= ~q; end end //*************code***********// endmodule
VL3 奇偶校验
按位异或即可。
`timescale 1ns/1ns module odd_sel( input [31:0] bus, input sel, output check ); //*************code***********// assign check = sel?(^bus):(~^bus); //*************code***********// endmodule
VL4 移位运算与乘法
写完才看到要求用移位运算,不过也简单,把乘法分解成移位相加即可。
注意把输入的d先保存起来。
`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]state; reg [7:0]d_r; always@(posedge clk or negedge rst) begin if(~rst)begin input_grant <= 1'b0; out <= 'd0; state <= 'd0; d_r <= 'd0; end else begin if(state == 0)begin input_grant <= 1'b1; out <= d; d_r <= d; state <= 1; end else if(state == 1)begin input_grant <= 1'b0; out <= 3 * d_r; state <= 2; end else if(state == 2)begin out <= 7 * d_r; state <= 3; end else if(state == 3)begin out <= 8 * d_r; state <= 0; end end end //*************code***********// endmodule
VL5 位拆分与运算
在sel==0时把d保存起来。
`timescale 1ns/1ns module 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]d_r; always@(*) begin case(sel) 0:begin validout=0; out=0; end 1:begin validout=1; out=d_r[3:0]+d_r[7:4]; end 2:begin validout=1; out=d_r[3:0]+d_r[11:8]; end 3:begin validout=1; out=d_r[3:0]+d_r[15:12]; end endcase end always@(posedge clk or negedge rst) begin if(~rst) d_r <= 'd0; else begin if(sel == 0) d_r <= d; end end //*************code***********// endmodule
VL6 多功能数据处理器
`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) begin if(~rst_n) c=0; else begin case(select) 0:c=a; 1:c=b; 2:c=a+b; 3:c=a-b; endcase end end endmodule
VL7 求两个数的差值
`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) begin if(~rst_n) c <= 'd0; else begin if(a>b) c<=a-b; else c<=b-a; end end endmodule
VL8 使用generate…for语句简化代码
这道题要求使用generate for语句,这个和for循环并不相同,首先generate for必须要使用genvar定义索引变量,其次generate for可以用来将一个模块例化多次,而for循环通常只是用于赋值。
这道题其实用for循环就够了。
`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 assign data_out[i]=data_in[7-i]; end endgenerate endmodule
VL9 使用子模块实现三输入数的大小比较
这题要求通过例化子模块实现三个数的大小比较,又由于子模块是时序逻辑,所以要经过两次比较,延两个周期。
`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]temp1; wire [7:0]temp2; child_mod u0( .clk(clk), .rst_n(rst_n), .a(a), .b(b), .c(temp1) ); child_mod u1( .clk(clk), .rst_n(rst_n), .a(a), .b(c), .c(temp2) ); child_mod u2( .clk(clk), .rst_n(rst_n), .a(temp1), .b(temp2), .c(d) ); endmodule module child_mod( input clk, input rst_n, input [7:0]a, input [7:0]b, output reg [7:0]c ); always@(posedge clk or negedge rst_n) begin if(~rst_n) c <= 'd0; else begin if(a<b) c<=a; else c<=b; end end endmodule
VL10 使用函数实现数据大小端转换
这题要求用function,注意一下function怎么写就行了。
`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]convert; input [3:0]in; integer i; for(i=0;i<4;i=i+1)begin convert[i] =in[3-i]; end endfunction assign c = convert(a); assign d = convert(b); endmodule