⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssramcon_sim.v

📁 各种基本单元的verilog模块.对初学者很有帮助的.
💻 V
字号:
/*********************************************************/
// MODULE:		SSRAM Controller simulation
//
// FILE NAME:	ssramcon_sim.v
// VERSION:		1.0
// DATE:		January 1, 1999
// AUTHOR:		Bob Zeidman, Zeidman Consulting
// 
// CODE TYPE:	Simulation
//
// DESCRIPTION:	This module provides stimuli for simulating
// an SSRAM memory controller. It uses an SSRAM model and
// performs a number of writes and reads to the model,
// including back-to-back reads and writes. It also checks
// the reset function.
//
/*********************************************************/

// DEFINES
`define DEL	1			// Clock-to-output delay. Zero
						// time delays can be confusing
						// and sometimes cause problems.
`define WAIT 2			// Number of wait cycles needed
						// Flow-through SSRAMs require
						// 	1 wait cycles
						// Pipelined SSRAMs require
						// 	2 wait cycle
`define DWIDTH 8		// Data bus width
`define ADEPTH 256		// Memory depth
`define AWIDTH 8		// Number of bits needed to
						// address memory 
`define CYCLE_TIME 100	// System clock cycle time

// TOP MODULE
module ssramcon_sim();

// INPUTS

// OUTPUTS

// INOUTS

// SIGNAL DECLARATIONS
reg					clock;
reg					reset;
reg					as;
reg					we;
reg					oe;
reg					ce;
reg					cs;			
wire				ack;

reg  [`DWIDTH-1:0]	data_out;	// Data written by processor
reg  [`DWIDTH-1:0]	data_exp;	// Data expected to be read
								// from memory
wire [`DWIDTH-1:0]	data;		// Data bus
reg  [`AWIDTH-1:0]	address;	// Address bus
reg  [`AWIDTH-1:0]	addr_count;	// Address counter

reg  [`DWIDTH-1:0]	data_patt;	// Data pattern holder
reg  [`WAIT-1:0]	as_shift;	// Shift register for as
reg  [`WAIT-1:0]	we_shift;	// Shift register for we

integer				fin_flag;	// Tells the simulation
								// when we're finished

// PARAMETERS

// ASSIGN STATEMENTS
// The data bus direction is determined by the address
// strobe and write enable signals from previous cycles.
assign data = (as_shift[`WAIT-1] & we_shift[`WAIT-1]) ?
				data_out : 8'hzz;

// MAIN CODE

// Instantiate the controller
ssram_control Ssram_control(
		.clock(clock),
		.reset(reset),
		.as(as),
		.ack(ack));

// Instantiate an SSRAM
ssram Ssram(
		.clock(clock),
		.oe(oe),
		.we(we),
		.ce(ce),
		.cs(cs),
		.address(address),
		.data(data));

// Generate the clock
always #(`CYCLE_TIME/2) clock = ~clock;

// Simulate
initial begin
	// Initialize inputs
	clock = 1;
	reset = 0;
	as_shift = 0;
	we_shift = 0;
	as = 0;
	cs = 1;
	oe = 1;
	ce = 1;

	// Test the reset signal
	#`DEL;
	// Assert the reset signal
	reset = 1;

	// Wait for the outputs to change asynchronously
	#`DEL
	#`DEL
	// Test outputs
	if (ack === 1'b0)
		$display ("Reset is working");
	else begin
		$display("\nERROR at time %0t:", $time);
		$display("Reset is not working");
		$display("    ack  = %b\n", ack);
		
		// Use $stop for debugging
		$stop;
	end

	// Deassert the reset signal
	reset = 0;

	// Initialize the address counter
	addr_count = 0;
	
	// Initialize the data pattern to be written
	data_patt = `DWIDTH'h1;

	// Write a series of values to memory
	while (&addr_count === 1'b0) begin
		// Write to memory
		writemem(addr_count, data_patt);

		// Increment the address counter
		addr_count = addr_count + 1;

		// Shift the data pattern
		data_patt <= (data_patt << 1);
		data_patt[0] <= data_patt[`DWIDTH-1];

		// Wait for the data pattern to change
		#`DEL;
	end
	// Write once more to memory
	writemem(addr_count, data_patt);

	// Wait for the access to complete
	#`DEL;

	// Initialize the address counter
	addr_count = 0;

	// Initialize the data pattern to be read
	data_patt = `DWIDTH'h1;

	// Verify the values that were written	
	while (&addr_count === 1'b0) begin 
		// Read from memory
		readmem(addr_count, data_patt);

		// Increment the address counter
		addr_count = addr_count + 1;

		// Shift the data pattern
		data_patt <= (data_patt << 1);
		data_patt[0] <= data_patt[`DWIDTH-1];

		// Wait for the data pattern to change
		#`DEL;
	end
	// Read once more from memory
	readmem(addr_count, data_patt);

	// Set the finish flag
	fin_flag = `WAIT;

	// Turn off chip select
	@(posedge clock);
	cs <= #`DEL 0;
end

// Shift the address strobe and write enable signals
// so that we can use them after the appropriate cycle
// delay
always @(posedge clock) begin
	// Shift the address strobe signal into 
	// the address strobe shift register
	as_shift <= #`DEL as_shift << 1;
	as_shift[0] <= #`DEL as;

	// Shift the write enable signal into
	// the write enable shift register
	we_shift <= #`DEL we_shift << 1;
	we_shift[0] <= #`DEL we;

	// Look for an acknowledge during the correct cycle
	if (as_shift[`WAIT-1] & ~ack) begin
		$display("\nERROR at time %0t:", $time);
		$display("Did not receive the expected acknowledge\n");

		// Use $stop for debugging
		$stop;
	end
	else if (~as_shift[`WAIT-1] & ack) begin
		$display("\nERROR at time %0t:", $time);
		$display("Received an unexpected acknowledge\n");

		// Use $stop for debugging
		$stop;
	end
end

// Perform any necessary signal checking
always @(data_exp) begin
	// Did we find the expected data?
	if (data !== data_exp) begin
		$display("\nERROR at time %0t:", $time);
		$display("Controller is not working");
		$display("    data written = %h", data_exp);
		$display("    data read    = %h\n", data);

		// Use $stop for debugging
		$stop;
	end

	// Are we done checking all reads?
	if (fin_flag === 0) begin
		$display("\nSimulation complete - no errors\n");
		$finish;
	end
	fin_flag = fin_flag - 1;
end

// TASKS
// Write data to memory
task writemem;

// INPUTS
input [`AWIDTH-1:0]	write_addr;		// Memory address
input [`DWIDTH-1:0]	write_data;		// Data to write to memory

// OUTPUTS

// INOUTS

// TASK CODE
begin
	// Wait for the rising clock edge
	@(posedge clock);
	we <= #`DEL 1;					// Set up a write access
	as <= #`DEL 1;					// Assert address strobe
	address <= #`DEL write_addr;	// Set up the address
									// Set up the data to change
									// at the correct cycle
	data_out <= #(`CYCLE_TIME * `WAIT + `DEL) write_data;
end
endtask		// writemem

// Read data from memory and check its value
task readmem;

// INPUTS
input [`AWIDTH-1:0]	read_addr;		// Memory address
input [`DWIDTH-1:0]	read_data;		// Expected read data

// OUTPUTS

// INOUTS

// TASK CODE
begin
	// Wait for the rising clock edge
	@(posedge clock);
	we <= #`DEL 0;				// Set up a read access
	as <= #`DEL 1;				// Assert address strobe
	address <= #`DEL read_addr;	// Set up the address

	// Set up the expected data
	data_exp <= #(`CYCLE_TIME * `WAIT + 2*`DEL) read_data;
end
endtask		// readmem

endmodule			// ssramcon_sim

// SUBMODULE
// SSRAM memory model
module ssram(
		clock,
		data,
		address,
		oe,
		ce,
		cs,
		we);

// INPUTS
input				clock;		// Clock
input [`AWIDTH-1:0]	address;	// Memory address
input				oe;		  	// Output enable
input	   			we;		  	// Write enable
input				ce;		  	// Clock enable
input				cs;		  	// Chip select

// OUTPUTS

// INOUTS
inout [`DWIDTH-1:0]	data;	  	// Data lines

// SIGNAL DECLARATIONS
wire				clock;
wire [`AWIDTH-1:0]	address;
wire				oe;
wire				we;
wire				ce;
wire				cs;
wire [`DWIDTH-1:0]	data;

reg  [`DWIDTH-1:0]	mem[`ADEPTH-1:0];  	// Stored data

// Shift register for storing addresses
// for pipelined accesses
reg  [`AWIDTH-1:0]	addr_shift[`WAIT-1:0];
// Shift register for storing write enable
// for pipelined accesses
reg  [`WAIT-1:0]	we_shift;
// Shift register for storing chip selecte
// for pipelined accesses
reg  [`WAIT-1:0]	cs_shift;

reg					i;			// Temporary variable

// PARAMETERS

// ASSIGN STATEMENTS

// Output the data if the SSRAM is enabled, the clock is
// enabled, oe is asserted, and the current access is a read
assign data = ce & oe & cs_shift[`WAIT-1] &
		~we_shift[`WAIT-1] ? mem[addr_shift[`WAIT-1]] : 8'hzz;

// MAIN CODE

// Initialize chip select shift register
initial begin
	cs_shift = 0;
end

// Look at the rising edge of clock
always @(posedge clock) begin
	// Don't do anything unless the clock is enabled
	if (ce) begin
		// Store the address and control signals
		// in their respective shift registers and shift them
		cs_shift <= #`DEL cs_shift << 1;
		cs_shift[0] <= #`DEL cs;
		we_shift <= #`DEL we_shift << 1;
		we_shift[0] <= #`DEL we;

		for (i = `WAIT-1; i > 0; i = i - 1) begin
			addr_shift[i] <= #`DEL addr_shift[i-1];
		end
		addr_shift[0] <= #`DEL address;

		// If there is a chip select and write enable,
		// write the data
		if (cs_shift[`WAIT-1] & we_shift[`WAIT-1]) begin
				mem[addr_shift[`WAIT-1]] <= #`DEL data;
		end
	end
end
endmodule		// sram

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -