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) 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
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) begin
if (!t_rstn) begin
des_sync_src_ack_1 <= 1'b0;
des_sync_src_ack_2 <= 1'b0;
end else begin
des_sync_src_ack_1 <= i_ack;
des_sync_src_ack_2 <= des_sync_src_ack_1;
end
end
wire des_sync_src_neg = !des_sync_src_ack_1 & des_sync_src_ack_2;
always @(posedge tclk or negedge t_rstn) begin
if (!t_rstn) begin
o_tx_data <= 'b0;
end else if (des_sync_src_neg) begin
o_tx_data <= i_data_in;
end
end
//=============================
//--o_req
//=============================
always @(posedge tclk or negedge t_rstn) begin
if (!t_rstn) begin
o_req <= 1'b0;
end else if (des_sync_src_ack_2) begin
o_req <= 1'b0;
end else begin
o_req <= 1'b1;
end
end
endmodule
//==============================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) begin
if (!r_rstn) begin
src_sync_des_req_1 <= 1'b0;
src_sync_des_req_2 <= 1'b0;
end else begin
src_sync_des_req_1 <= i_req;
src_sync_des_req_2 <= src_sync_des_req_1;
end
end
always @(posedge rclk or negedge r_rstn) begin
if (!r_rstn) begin
o_ack <= 1'b0;
end else begin
o_ack <= src_sync_des_req_2;
end
end
always @(posedge rclk or negedge r_rstn) begin
if (!r_rstn) begin
o_rx_data <= 'b0;
end else if (src_sync_des_req_2) begin
o_rx_data <= i_data_in;
end else begin
o_rx_data <= o_rx_data;
end
end
endmodule
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]};
endmodule
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
【REF】
1.https://blog.csdn.net/yueqiu693/article/details/125073144