LocalBUS总线读写寄存器的Verilog代码实现(一)

LocalBUS总线读写寄存器的Verilog代码实现(一)

应用背景

在FPGA内部,经常需要实现一些寄存器功能,这些寄存器可以通过外部的localbus并行总线或其它串行总线来访问。本文所设计的模块先考虑并行情况,针对串行总线的情况,需要增加另外的串转并模块,请参阅其它博文。
模块所涉及的信号主要是地址、双向数据、片选、读、写,用到的知识就是数字电路里的译码器,地址总线上送来的一组数据满足FPGA内部的地址时,访问寄存器信号有效。然后依据是读有效还是写有些,分别实现不同的功能。

注意事项

  1. 总线描述的时候,一定要注意位宽是放在变量名称的前面,如果放在后面,则是表示变量的某一位,或者表示某个内存地址。
    比如:
    [7:0]BMD,表示8位宽度的BMD总线;
    BMD[7:0],表示BMD的bit7到bit0;
    [7:0]BMD[7:0],表示一个数据,或者叫矩阵,8个位宽是8位矩阵。
  2. 需要注意地址锁存的条件,写操作时,判断的是nBWE的上升沿;读操作判断nBOE的下降沿。实际应用时需要留意锁存的时序条件是否满足,可以根据实际选择使用上升沿还是下降沿。如果存在锁存失败的情况,需要改为判断Clk上升沿,做成时序逻辑。

always@(posedge Clk )
begin
if (~Rst_n && nBWE)

  1. 双向端口不能在模块间传递,意思是只能顶层定义双向端口,然后在顶层模块里分别实现读写寄存器,然后往下一层模块传递数据。
  2. testbench文件请参考下一篇博文。

代码如下:

module regs(
	Clk,  //时钟
	Rst_n, //复位信号,低有效
	BMA,  //地址信号
	BMD,  //数据信号
	nBOE, //读信号,低有效
	nBWE, //写信号,低有效
	nBCS1 //片选信号,低有效
);

input Clk;
input Rst_n;
input [7:0]BMA;

inout [7:0]BMD;

input nBOE;
input nBWE;
input nBCS1;


//CPLD Registers
reg 	[7:0]SFTDog_reg;
reg 	[7:0]Read_reg_data;
reg 	[7:0]Test_reg ;

reg	[7:0]cpld_ver = 8'b0010_0001;		//CPLD major revision

reg 	system_rst = 1'b0;				//CPLD software reset

wire SFTDog_CS;

localparam [7:0]
		ADDR_HDDog_Close            = 8'h060,	// F500_180  ADDR[9:2]
		
		ADDR_Test_reg					 = 8'h061,	// F500_184
		
		ADDR_SFTDog_CS              = 8'h071,  // F500_01C4
		ADDR_SFTDog_Clr             = 8'h072;  // F500_01C8
		
	
	assign SFTDog_CS    = (!nBCS1  &&  (BMA[7:0] == ADDR_SFTDog_CS[7:0])) ? 1'b0 : 1'b1;	

// write logic	
//	always@(posedge Clk  or  negedge Rst_n)
//		if (!Rst_n)		
//			SFTDog_reg <= 8'h38;
//		else if (!SFTDog_CS && !nBWE)	
//			SFTDog_reg <=  BMD;


// write logic			写逻辑实现	
always@(posedge nBWE or negedge Rst_n )                               
	begin
		if (~Rst_n)												//Set CPLD registers to default value
			begin
				SFTDog_reg <= 8'h38;
				Test_reg <= 8'b0011_1100;
			end

		else if (~nBCS1)
			begin
				case (BMA[7:0])
					ADDR_SFTDog_CS:	SFTDog_reg <=  BMD;
											
					ADDR_Test_reg:		Test_reg <= BMD;
//						4:	soft_mux_on1[7:0] <= cpld_data[7:0];
//						5:	cfg_rcw_src1[7:0] <= cpld_data[7:0];
//		在此处添加更多的寄存器	
				endcase
			end
	end			
			

			
//read registers 读逻辑实现
assign BMD[7:0] = (!nBCS1 && !nBOE) ?	Read_reg_data[7:0]	:	8'bzzzz_zzzz;

always@(negedge nBOE)                
	begin
		if (~nBCS1)
			begin
				case (BMA[7:0])

					ADDR_SFTDog_CS:	Read_reg_data[7:0] <= SFTDog_reg;
					ADDR_Test_reg:		Read_reg_data[7:0] <= Test_reg ;
                   //在此处添加更多的寄存器
					default:	Read_reg_data[7:0]<=8'bzzzz_zzzz;
				endcase	
			end
	end
	
endmodule
		

猜你喜欢

转载自blog.csdn.net/malcolm_110/article/details/103934639