IC/FPGA手撕代码系列(一):轮询仲裁器、异步握手信号处理、序列检测、格雷码转换

前言:该系列会不断更新,心愿是覆盖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

  • 2
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

俩个圆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值