前言:该系列会不断更新,心愿是覆盖ic中常见的一些设计思想和设计方法
目录
一、轮询仲裁器
轮询仲裁器逻辑特点:
a. 基于次序的优先级:小号输入口的优先级高于大号输入口;
b. 最高优先级是循环的,RR逻辑中,最高优先级并不总是0,而是根据上一次选择的输入口而变化的。上一次选择的输入口的下一个输入口具有最高的优先级。同时最高优先级并不是逐个向后轮换的,而是根据上一次选择的输入口可能产生跳变
一个四请求的轮询仲裁器实现
module rr_arbiter
(
input clk,
input rst_n,
input [3:0]req,
input req_en,
output[3:0]grant_arb
);
reg [3:0] state_c_arb;
reg [3:0] state_n_arb;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state_c_arb<=0;
end
else if(req_en)begin
state_c_arb=state_n_arb;
end
else begin
state_c_arb<=0;
end
end
always @(*) begin
if (!rst_n) begin
state_n_arb<=0;
end
else begin
case(state_c_arb)
4'b0001:begin
case(1'b1)
req[1]:state_n_arb<=4'b0010;
req[2]:state_n_arb<=4'b0100;
req[3]:state_n_arb<=4'b1000;
req[0]:state_n_arb<=4'b0001;
default:state_n_arb<=4'b0001;
endcase
end
4'b0010:begin
case(1'b1)
req[2]:state_n_arb<=4'b0100;
req[3]:state_n_arb<=4'b1000;
req[0]:state_n_arb<=4'b0001;
req[1]:state_n_arb<=4'b0010;
default:state_n_arb<=4'b0010;
endcase
end
4'b0100:begin
case(1'b1)
req[3]:state_n_arb<=4'b1000;
req[0]:state_n_arb<=4'b0001;
req[1]:state_n_arb<=4'b0010;
req[2]:state_n_arb<=4'b0100;
default:state_n_arb<=4'b0100;
endcase
end
4'b1000:begin
case(1'b1)
req[0]:state_n_arb<=4'b0001;
req[1]:state_n_arb<=4'b0010;
req[2]:state_n_arb<=4'b0100;
req[3]:state_n_arb<=4'b1000;
default:state_n_arb<=4'b1000;
endcase
end
default:state_n_arb<=4'b0001;
endcase
end
end
assign grant_arb=state_n_arb;
endmodule
二、异步握手信号处理
基本时序图
1)、top层:
module asynchronous_data(
input tclk,
input rclk,
input rstn,
input rrstn,
input [4:0] data_in,
output[4:0]data_out
);
wire req;
wire ack;
reg [4:0]tx_data;
tx tx_module(
.tclk(tclk),
.rstn(rstn),
.ack(rrstn),
.data_in(data_in),
.req(req),
.tx_data(tx_data)
);
rx rx_1(
.rclk(rclk),
.rrstn(rrstn),
.req(req),
.data_in(tx_data),
.ack(ack),
.rx_data(data_out)
);
endmodule
2)、数据发送模块
module tx(
input tclk,
input rstn,
input ack,
input [4:0] data_in,
output req,
output reg[4:0]tx_data
);
wire ack_sync;
reg ack_sync1;
reg req_reg;
wire ack_syn_negedge;
always@(posedge tclk or negedge rstn)begin
if(!rstn)begin
tx_data<=0;
end
else if(ack_syn_negedge)begin
tx_data<=data_in;
end
end
reg_module reg_module1(
.clk(tclk),
.sig(ack),
.rstn(rstn),
.sig_reg(ack_sync)
);
always@(posedge tclk or negedge rstn)begin
if(!rstn)begin
ack_sync1<=0;
end
else if(ack_syn_negedge)begin
ack_sync1<=ack_sync;
end
end
assign ack_syn_negedge=!ack_sync&ack_sync1;
always@(posedge tclk or negedge rstn)begin
if(!rstn)begin
req_reg<=0;
end
else if(ack_sync)begin
req_reg<=0;
end
else begin
req_reg<=1;
end
end
assign req= req_reg;
endmodule
3)、数据接收模块
module rx(
input rclk,
input rrstn,
input req,
input [4:0] data_in,
output ack,
output reg [4:0]rx_data
);
wire req_sync;
always@(posedge rclk or negedge rrstn)begin
if(!rrstn)begin
rx_data<=0;
end
else if(req_sync)begin
rx_data<=data_in;
end
end
reg_module reg_module1(
.clk(rclk),
.sig(req),
.rstn(rrstn),
.sig_reg(req_sync)
);
assign ack =req_sync;
endmodule
4)、reg_module信号寄存模块
module reg_module(
input clk,
input rstn,
input sig,
output reg sig_reg
);
reg sig_reg0;
always@(posedge clk or negedge rstn)begin
if(!rstn)begin
sig_reg0<=0;
sig_reg<=0;
end
else begin
sig_reg0<=sig;
sig_reg<=sig_reg0;
end
end
endmodule
三、序列检测
1)、移位寄存器实现
检测到序列为1010时,输出响应信号
module fsm_shift(clk,rst_n,din,dout_vld);
input clk;
input rst_n;
input din;
output reg dout_vld;
reg [3:0]din_reg;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
din_reg<=0;
else
din_reg<={din_reg[2:0],din};
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
dout_vld<=0;
else if(din_reg==4'b1010)
dout_vld<=1;
else
dout_vld<=0;
end
endmodule
2)、状态机实现
module fsm_1010(clk,
rst_n,
x,
z);
input clk;
input rst_n;
input x;
output z;
reg z;
reg[2:0]state_c; //现态、次态定义
reg[2:0]state_n;
parameter S0=3'b000; //状态参数定义
parameter S1=3'b001;
parameter S2=3'b010;
parameter S3=3'b011;
parameter S4=3'b100;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
state_c<=S0;
end
else begin
state_c<=state_n;
end
end
always@(*)begin
case(state_c)
S0:begin
if(x==1)begin
state_n<=S1;
end
else begin
state_n<=S0;
end
end
S1:begin
if(x==0)begin
state_n<=S2;
end
else begin
state_n<=S1;
end
end
S2:begin
if(x==1)begin
state_n<=S3;
end
else begin
state_n<=S0;
end
end
S3:begin
if(x==0)begin
state_n<=S4;
end
else begin
state_n<=S1;
end
end
S4:begin
if(x==1)begin
state_n<=S1;
end
else begin
state_n<=S0;
end
end
default:state_n<=S0;
endcase
end
always@(*)begin
if(state_c==S4)begin
z<=1'b1;
end
else begin
z<=1'b0;
end
end
endmodule
四、格雷码转换
1)、二进制到格雷码的转换,法则是保留二进制码的最高位作为格雷码的最高位,而次高位格雷码为二进制码的高位与次高位相异或
module gray_trans
#(parameter SIZE=8)
(
input [SIZE-1] bin,
output[SIZE-1] gray,
);
assign gray=bin^{1'b0,bin[SIZE-1:1]};
endmodule
2)、格雷码到二进制的转换,法则是保留格雷码的最高位作为自然二进制码的最高位,而次高位自然二进制码为高位自然二进制码与次高位格雷码相异或
module gray_trans
#(parameter SIZE=8)
(
input [SIZE-1:0] gray,
output[SIZE-1]:0 bin
);
assign bin[SIZE-1]=gray[SIZE-1];
genvar i;
generate
for (i=SIZE-2;i>0;i=i-1)
begin:trans
assign bin[i]=gray[i]^bin[i+1];
end
endgenerate
endmodule