SV interface and Program3

时钟域的理解

  • 在仿真过程中,时钟跳变的一瞬间,CPU将时间域划分为不同的时钟域执行不同的代码
  • 信号在芯片中都是金属丝,在进行跳变的时候都是电容的充放电过程,通常使用时钟上升沿进行模拟,而不使用时钟下降沿

	// define the interface
interface mem_if(input wire clk);
	logic				reset;     // logic可以作为输入和输出
	logic				we_sys;
	logic				cmd_valid_sys;
	logic				ready_sys;
	logic	[7:0] 		data_sys;
	logic	[7:0]		addr_sys;
	logic				we_mem;
	logic				ce_mem;
	logic	[7:0]		datao_mem;
	logic	[7:0]		datai_mem;
	logic	[7:0]		addr_mem;
	

	// modport for meomry controller interface	
	modport ctrl	(
		input clk,reset,we_sys,cmd_valid_sys,addr_sys,datao_mem,
		output we_mem,ce_mem,addr_mem,datai_mem,ready_sys,
		ref data_sys
	);
	
	//modport for memory model interface
	modport meomry	(
		input clk,reset,we_mem,ce_mem,addr_mem,datai_mem,
		output datao_mem
	);
	// modport for test program
	modport test (
		input clk,ready_sys,
		output reset,we_sys,cmd_valid_sys,addr_sys,
		ref data_sys
	);

endinterface


	// memory model design with interface
	// 传入modport接口
module memory_model (mem_if.memory mif);	
	// memory array
	logic [7:0] mem [0:255];
	
	//write logic 
	always @(posedge mif.clk)
		if(mif.ce_mem && mif.we_mem) begin
			mem[mif.addr_mem] <= mif.datai_mem;
		end
	
	// read logic
	always @(posedge mif.clk)
		if(mif.ce_mem && ~mif.we_mem) begin
			datao_mem <= mem[mif.addr_mem];
		end
endmodule


	// memory controller design with interface
	
module memory_ctrl(mem_if.ctrl cif);
	typedef enum {IDLE,WRITE,READ,DONE} fsm_t;
	fsm_t state;
	
	always @(posedge cif.clk)
		if(cif.reset) begin
			state	<= IDLE;
			cif.we_mem <=	0;
			cif.ce_mem <=	0;
			cif.addr_mem <= 0;
			cif.datai_mem <= 0;
			cif.data_sys <=0;
		end
		else begin
			case(state)
				IDLE: begin
					cif.ready_sys <= 1'b0;
					if(cif.cmd_valid_sys && cif.we_sys) begin
						cif.addr_mem <= cif.addr_sys;
						cif.datai_mem <= cif_data_sys;
						cif.we_mem <= 1'b1;
						cif.ce_mem <= 1'b1;
						state <= WRITE;
					end
					if(cif.cmd_valid_sys && ~cif.we_sys) begin
						cif.addr_mem <= cif.addr_sys;
						cif.datai_mem <= cif_data_sys;
						cif.we_mem <= 1'b0;
						cif.ce_mem <= 1'b1;
						state <= READ;
					end
				end
				WRITE: begin
					cif.ready_sys <= 1'b1;
					if(~cif.cmd_valid_sys) begin
						cif.addr_mem <= 8'b0;
						cif.datai_mem <= 8'b0;
						cif.we_mem <= 1'b0;
						cif.ce_mem <= 1'b0;
						state <= IDLE;
					end
				end
				
				READ: begin
					cif.ready_sys <= 1'b1;
					if(~cif.cmd_valid_sys) begin
						cif.addr_mem <= 8'b0;
						cif.datai_mem <= 8'b0;
						cif.we_mem <= 1'b0;
						cif.ce_mem <= 1'b0;
						cif.ready_sys <= 1'b1;
						state <= IDLE;
						cif.data_sys <= 8'bz;
					end
				end
			endcase
		end
endmodule



program test(mem_if.test tif);

	initial begin
		tif.reset <= 1;
		tif.we_sys <= 0;
		tif.cmd_valid_sys <= 0;
		tif.addr_sys <= 0;
		tif.data_sys <= 8'bz;
		#100 tif.reset <= 0;;
		for(int i = 0;i<4;i++) begin
			@(posedge tif.clk)
			tif.we_sys <= 1;
			tif.cmd_valid_sys <= 1;
			tif.addr_sys <= 1;
			tif.data_sys <= $random;
			@(posedge tif.clk)
			tif.we_sys <= 0;
			tif.cmd_valid_sys <= 0;
			tif.addr_sys <= 0;
			tif.data_sys <= 8'bz;
		end
		repeat(10) (posedge tif.clk)
		// 此模块没有写完....
	end


endprogram



module	top();
	logic clk = 0;
	always #10 clk++;
	
	mem_if 			u_miff(clk);
	memory_ctrl 	u_ctrl(u_miff);
	meomry_model 	u_model(u_miff);
	test			u_test(u_miff);


endmodule
posted @ 2023-12-27 23:00  Icer_Newer  阅读(18)  评论(0编辑  收藏  举报