IC每日一题:IC常用模块--RR/handshake/gray2bin
- 1 RR仲裁器
- 2 异步握手信号处理
- 3 格雷码和二进制相互转换
1 RR仲裁器
应用:在多个FIFO请求pop时存在仲裁策略,还有比如多master申请总线控制权的仲裁等这些应用场合;假如当前是最高优先级,下一次就是最低优先级;
RR_arbiter是公平性的仲裁器,基于顺序轮转优先级,最高优先级是循环的;
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) beginif (!rst_n) beginstate_c_arb<=0;endelse if(req_en)beginstate_c_arb<=state_n_arb;endelse beginstate_c_arb<=0;end
endalways @(*) beginif (!rst_n) beginstate_n_arb<=0;endelse begincase(state_c_arb)4'b0001:begincase(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;endcaseend4'b0010:begincase(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;endcaseend4'b0100:begincase(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;endcaseend4'b1000:begincase(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;endcaseenddefault:state_n_arb<=4'b0001;endcaseend
end
assign grant_arb=state_n_arb;endmodule
2 异步握手信号处理
题目时序图如下:
//==========================================================
//--Author : colonel
//--Date : 11-14
//--Module : asy_handshake_data
//--Function: use handshake to asy the data
//==========================================================
module asy_handshake_data(input tclk,input t_rstn,input rclk,input r_rstn,input [4:0] data_in,output [4:0] data_out
);//==========================< 信号 >=========================
wire ack;
wire req;
reg [4:0] data_reg;//==========================< instance >====================
tx u_tx(.tclk(tclk),.t_rstn(t_rstn),.i_ack(ack),.i_data_in(data_in),.o_req(req),.o_tx_data(data_reg)
);rx u_rx(.rclk(rclk),.r_rstn(r_rstn),.i_req(req),.i_data_in(data_reg),.o_ack(ack),.o_rx_data(data_out)
);endmodule//=============================tx_module=====================
module tx (input tclk,input t_rstn,input i_ack,input [4:0] i_data_in,output reg o_req,output reg[4:0] o_tx_data
);//==========================< 信号 >=========================
reg des_sync_src_ack_1;
reg des_sync_src_ack_2;always @(posedge tclk or negedge t_rstn) beginif (!t_rstn) begindes_sync_src_ack_1 <= 1'b0;des_sync_src_ack_2 <= 1'b0;end else begindes_sync_src_ack_1 <= i_ack;des_sync_src_ack_2 <= des_sync_src_ack_1;end
endwire des_sync_src_neg = !des_sync_src_ack_1 & des_sync_src_ack_2;always @(posedge tclk or negedge t_rstn) beginif (!t_rstn) begino_tx_data <= 'b0;end else if (des_sync_src_neg) begino_tx_data <= i_data_in;end
end//=============================
//--o_req
//=============================
always @(posedge tclk or negedge t_rstn) beginif (!t_rstn) begino_req <= 1'b0;end else if (des_sync_src_ack_2) begino_req <= 1'b0;end else begino_req <= 1'b1;end
endendmodule//==============================rx module===========
module rx(input rclk,input r_rstn,input i_req,input [4:0] i_data_in,output reg o_ack,output reg [4:0] o_rx_data
);
//==========================< 信号 >=========================
reg src_sync_des_req_1;
reg src_sync_des_req_2;always @(posedge rclk or r_rstn) beginif (!r_rstn) beginsrc_sync_des_req_1 <= 1'b0;src_sync_des_req_2 <= 1'b0;end else beginsrc_sync_des_req_1 <= i_req;src_sync_des_req_2 <= src_sync_des_req_1;end
endalways @(posedge rclk or negedge r_rstn) beginif (!r_rstn) begino_ack <= 1'b0;end else begino_ack <= src_sync_des_req_2;end
endalways @(posedge rclk or negedge r_rstn) beginif (!r_rstn) begino_rx_data <= 'b0;end else if (src_sync_des_req_2) begino_rx_data <= i_data_in;end else begino_rx_data <= o_rx_data;end
endendmodule
3 格雷码和二进制相互转换
二进制码转换为格雷码: 从最右边一位开始,依次将每一位与它左边的一位进行异或操作(XOR),得到的结果就是格雷码。
格雷码转换为二进制码:从最右边一位开始,依次将每一位与它左边的一位进行异或操作,但是需要注意的是,每次异或操作的结果需要与左边的原始位进行比较,如果不同,则将结果取反
module gray_trans#(parameter SIZE=8
)(input [SIZE-1] bin,output[SIZE-1] gray,
);assign gray=bin^{1'b0,bin[SIZE-1:1]};
endmodulemodule gray_trans#(parameter SIZE=8
)(input [SIZE-1:0] gray,output[SIZE-1]:0 bin
);assign bin[SIZE-1]=gray[SIZE-1];genvar i;generatefor (i=SIZE-2;i>0;i=i-1)begin:transassign bin[i]=gray[i]^bin[i+1];endendgenerate
endmodule
【REF】
1.https://blog.csdn.net/yueqiu693/article/details/125073144