📄 state_sim.v
字号:
/*********************************************************/
// MODULE: State machine simulation
//
// FILE NAME: state_sim.v
// VERSION: 1.0
// DATE: January 1, 1999
// AUTHOR: Bob Zeidman, Zeidman Consulting
//
// CODE TYPE: Simulation
//
// DESCRIPTION: This module provides stimuli for simulating
// a memory controller state machine. It uses a simple,
// one-location memory and performs a number of writes and
// reads, 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 DWIDTH 8 // Width of data
// TOP MODULE
module state_sim();
// INPUTS
// OUTPUTS
// INOUTS
// SIGNAL DECLARATIONS
reg clock;
reg reset_n;
reg write;
reg read;
wire ready;
wire out_en;
wire write_en;
wire ack;
reg [`DWIDTH-1:0] data_out;
wire [`DWIDTH-1:0] data;
reg drd_ready; // Delayed read ready output
integer cyc_count; // Count cycles to determine
// if the access has taken
// too long
// PARAMETERS
// ASSIGN STATEMENTS
assign #`DEL data = read ? `DWIDTH'hzz : data_out;
// MAIN CODE
// Instantiate the state machine
state_machine machine1(
.clock(clock),
.reset_n(reset_n),
.wr(write),
.rd(read),
.ready(ready),
.out_en(out_en),
.write_en(write_en),
.ack(ack));
// Instantiate a memory
memory memory1(
.clock(clock),
.wr(write),
.rd(read),
.data(data),
.ready(ready));
// Generate the clock
always #100 clock = ~clock;
initial begin
// Initialize inputs
clock = 0;
reset_n = 1;
write = 0;
read = 0;
// Test the asynchronous reset
reset_n = 0; // Assert the reset signal
// Wait for the outputs to change asynchronously
#`DEL
#`DEL
// Test outputs
if ((out_en === 1'b0) && (write_en === 1'b0) &&
(ack === 1'b0))
$display ("Reset is working");
else begin
$display("\nERROR at time %0t:", $time);
$display("Reset is not working");
$display(" out_en = %b", out_en);
$display(" write_en = %b", write_en);
$display(" ack = %b\n", ack);
// Use $stop for debugging
$stop;
end
// Deassert the reset signal
reset_n = 1;
// Write to memory
writemem(`DWIDTH'h5A);
// Read from memory
readmem(`DWIDTH'h5A);
// Read from memory
readmem(`DWIDTH'h5A);
// Write to memory
writemem(`DWIDTH'h00);
// Write to memory
writemem(`DWIDTH'hFF);
// Read from memory
readmem(`DWIDTH'hFF);
$display("\nSimulation complete - no errors\n");
$finish;
end
always @(posedge clock) begin
// Create delayed read ready
drd_ready <= #`DEL (ready && read);
// Check whether an access is taking too long
if (cyc_count > 5) begin
$display("\nERROR at time %0t:", $time);
$display("Read access took to long\n");
// Use $stop for debugging
$stop;
end
// Check the ack output
if (write_en) begin
if (~ack) begin
$display("\nERROR at time %0t:", $time);
$display("Write access - ack is not asserted\n");
// Use $stop for debugging
$stop;
end
end
else if (drd_ready) begin
if (~ack) begin
$display("\nERROR at time %0t:", $time);
$display("Read access - ack is not asserted\n");
// Use $stop for debugging
$stop;
end
end
else if (ack) begin
$display("\nERROR at time %0t:", $time);
$display("No access - ack is asserted\n");
// Use $stop for debugging
$stop;
end
end
// TASKS
// Write data to memory
task writemem;
// INPUTS
input [`DWIDTH-1:0] write_data; // Data to write to memory
// OUTPUTS
// INOUTS
// TASK CODE
begin
// Wait for the rising clock edge
@(posedge clock);
read <= #`DEL 0; // Deassert the read controls
write <= #`DEL 1; // Assert the write control
data_out <= write_data;
// Wait for one cycle
@(posedge clock);
end
endtask // writemem
// Read data from memory and check its value
task readmem;
// INPUTS
input [`DWIDTH-1:0] expected; // Expected read data
// OUTPUTS
// INOUTS
// TASK CODE
begin
cyc_count = 0; // Initialize the cycle count
// Wait for the rising clock edge
@(posedge clock);
read <= #`DEL 1; // Assert the read control
write <= #`DEL 0; // Deassert the write control
data_out = `DWIDTH'hxx; // Put out undefined data
// Wait for the ready signal
@(posedge clock);
while (~ready) begin
// Increment the cycle count
cyc_count = cyc_count + 1;
@(posedge clock);
end
// Did we find the expected data?
if (ready === 1) begin
if (data === expected) begin
$display ("Memory is working");
end
else begin
$display("\nERROR at time %0t:", $time);
$display("Memory is not working");
$display(" data written = %h", expected);
$display(" data read = %h\n", data);
// Use $stop for debugging
$stop;
end
end
end
endtask // readmem
endmodule // state_sim
// SUBMODULE
// One byte memory for simulation
module memory(
clock,
data,
wr,
rd,
ready);
// INPUTS
input clock; // Clock input
input wr; // Write input
input rd; // Read input
// OUTPUTS
output ready; // Is the memory ready?
// INOUTS
inout [`DWIDTH-1:0] data; // Data lines
// SIGNAL DECLARATIONS
wire clock;
wire wr;
wire rd;
reg ready;
wire [`DWIDTH-1:0] data;
reg [`DWIDTH-1:0] mem; // Stored data
reg [2:0] count; // Counter to assert ready
// PARAMETERS
// ASSIGN STATEMENTS
assign #`DEL data = rd ? mem : `DWIDTH'bzz;
// MAIN CODE
initial begin
count = 0;
$random(0); // Initialize random number generator
end
always @(posedge clock) begin
ready <= #`DEL 1'b0;
if ((wr === 1) && ~ready) begin
mem <= #`DEL data;
ready <= #`DEL 1'b1;
end
else if (rd === 1) begin
if (count === 0)
count = {$random} % 8 + 1;
if (count !== 0) begin
count = count - 1;
if (count === 0) begin
ready <= #`DEL 1'b1;
end
end
end
end
endmodule // memory
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -