四选一多路器_牛客题霸_牛客网
`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)——异步复位同步释放问题
//异步复位同步释放
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
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
`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
注意这题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
输出又是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
注意补位宽
`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
`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
不要忘了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
这题不纠结了 我会用时序逻辑来做
至于为什么分两个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来比较
注意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