牛客网刷题 入门篇 基础语法

VL1 四选一多路器

四选一多路器_牛客题霸_牛客网

`timescale 1ns/1ns
module mux4_1(
input [1:0]d1,d2,d3,d0,
input [1:0]sel,
output wire [1:0]mux_out
);
//*************code***********//
    //assign mux_out = (sel == 'd0)?d3:(sel == 'd1)?d2:(sel == 'd2)?d1:d0;

    reg [1:0] mux_out_reg ;
    always@(*)begin
        case(sel)
            2'd0: mux_out_reg = d3;
            2'd1: mux_out_reg = d2;
            2'd2: mux_out_reg = d1;
            2'd3: mux_out_reg = d0;
            default: mux_out_reg = d0;
        endcase
    end
    
    assign mux_out = mux_out_reg;
//*************code***********//
endmodule

异步复位同步释放

 异步复位同步释放,既能很快的检测到复位信号,不需要复位保持超过一个时钟周期,又能解决释放时的亚稳态问题(降低亚稳态发生的概率)

联发科数字IC简答题(9)——异步复位同步释放问题

牛客网刷题 入门篇 基础语法_第1张图片

//异步复位同步释放
module rst_sync(
 input clk,
 input rst_async_n,
 output rst_sync_n
);

reg [1:0] sync_rst_n;

always@(posedge clk or negedge rst_async_n)begin
    if(!rst_async_n)
        sync_rst_n <= 1'b0; //异步复位
    else
        sync_rst_n <= {sync_rst_n[0],1'b1}; //同步释放
end

assign rst_async_n = sync_rst_n[1];
endmodule 

VL2 异步复位的串联T触发器

T触发器: 输入是1,输出翻转; 输入是0,输出保持;

`timescale 1ns/1ns
module Tff_2 (
input wire data, clk, rst,
output reg q  
);
//*************code***********//
reg data1;

always@(posedge clk or negedge rst)begin
    if(!rst)begin
        data1 <= 'd0; 
        q     <= 'd0;
    end else begin
        if(data)
           data1 <= !data1;
        else
           data1 <= data1;
        if(data1)
            q    <= !q;
        else
            q    <= q;

    end
end

//*************code***********//
endmodule

VL3 奇偶校验

`timescale 1ns/1ns
module odd_sel(
input [31:0] bus,
input sel,//0奇1偶
output check
);
//*************code***********//
wire ji_check,ou_check;

assign ji_check = !(^ bus); 
assign ou_check = ^ bus;
assign check = sel ? ou_check : ji_check;

//*************code***********//
endmodule

VL4 移位运算与乘法

注意这题input_grant是用来采样的。要用一个寄存器保持住再做乘法。

`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)begin
    if(!rst)
        cnt <= 'd0;
    else
        cnt <= cnt + 1'b1;
end

always@(posedge clk or negedge rst)begin
    if(!rst)begin
        input_grant = 'd0;
        din <= 'd0;
    end else begin
        if(cnt == 'd0)begin
            input_grant <= 1'b1;
            din <= d;
        end
        else begin
            input_grant <= 1'b0;
            din <= din;
        end
    end
end

always@(posedge clk or negedge rst)begin
    if(!rst)begin
        out <= 'd0;
    end else begin
        case(cnt)
            2'd0: out <= d;
            2'd1: out <= (din << 2) - din;
            2'd2: out <= (din << 3) - din; 
            2'd3: out <= din << 3;
        endcase
    end
end
//*************code***********//
endmodule

 

 VL5 位拆分与运算

输出又是wire 懒的改 直接把端口开成reg了

`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***********//
always@(posedge clk or negedge rst)begin
    if(!rst)begin
        validout <= 'd0;
        out <= 'd0;    
    end else begin
    case(sel)
        'd0:
            begin
                validout <= 'd0;
                out <= 'd0;
            end
        'd1:
            begin
               validout <= 'd1;
               out <= d[3:0] + d[7:4]; 
            end
        'd2:
            begin
                validout <= 'd1;
                out <= d[3:0] + d[11:8];
            end
        'd3:
            begin
                validout <= 'd1;
                out <= d[3:0] + d[15:12];
            end
        default:
            begin
                validout <= 'd0;
                out <= 'd0;
            end
    endcase
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 <= 'd0;
    else begin
        case(select)
            'd0: c <= a; 
            'd1: c <= b; 
            'd2: c <= {a[7],a} + {b[7],b}; 
            'd3: c <= {a[7],a} - {b[7],b}; 
            default:c <= 'd0;
        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 <= {1'b0,a} - {1'b0,b};
        else 
            c <= {1'b0,b} - {1'b0,a};
    end
end
endmodule

VL8 使用generate…for语句简化代码

不要忘了generate begin后面有个标签

`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'b1)begin:reverse
        assign data_out[i] = data_in[7 - i];
    end
endgenerate
endmodule

VL9 使用子模块实现三输入数的大小比较

这题不纠结了 我会用时序逻辑来做 

至于为什么分两个module不对

需要调用3个模块,这里很多同学可能疑惑为什么用3个而不是2个。
第一个模块:比较 T 时刻的 a 和 b,T+1 时刻出来 tmp1; 第二个模块:比较 T 时刻的 a 和 c,T+1 时刻
出来 tmp2; 第三个模块:比较 T+1 时刻的 tmp1 和 tmp2,T+2 时刻出来 d;
如果只用2个子模块,那么 T 时刻比较 a 和 b 得到 tmp1,再比较 tmp1 和 c 的时候是 T+1 时刻的 c
和 T+1 时刻的 tmp1,而 tmp1 代表的是 T 时刻 a 和 b 的较小值,所以这时候比较的 T 时刻的 a、b
和 T+1 时刻的 c,显然不符合要求。

就是说要保持住同一时间的abc来比较 

VL10 使用函数实现数据大小端转换

注意for循环里没有assign啊

`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] inv;
    input [3:0] data_in;
    integer i;
    for(i = 0;i < 4;i = i + 1)begin
        inv[i] = data_in[3-i]; 
    end
endfunction

assign c = inv(a);
assign d = inv(b);
endmodule

你可能感兴趣的:(手撕代码总结,fpga开发)