aboutsummaryrefslogtreecommitdiff
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/slave.v107
1 files changed, 61 insertions, 46 deletions
diff --git a/models/slave.v b/models/slave.v
index 9c58ffd..4f2cb5c 100644
--- a/models/slave.v
+++ b/models/slave.v
@@ -11,21 +11,26 @@
module memory_slave_model
#(
parameter SLAVE_NR = -1,
+ parameter WORD_SIZE = 2, /* in bytes */
+ parameter GRANULARITY = 2, /* in bytes */ /* we'll use that soon */
+ parameter ADR_BITS = 18,
/* Changing the following 3 allows us to make it function as ROM */
parameter WRITABLE = 1,
parameter WORDS_TO_INITIALIZE = 0,
parameter INITIAL_CONTENTS_FILE = "some_file.mem"
)
(
- output wire ACK_O,
- input wire CLK_I,
- input wire [17:0] ADR_I,
- input wire [15:0] DAT_I,
- output wire [15:0] DAT_O,
- input wire RST_I,
- input wire STB_I,
- input wire WE_I,
- output wire STALL_O
+ output wire ACK_O,
+ /* output wire ERR_O, */ /* we might use it one day */
+ input wire CLK_I,
+ input wire [ADR_BITS - 1 : 0] ADR_I,
+ input wire [8*WORD_SIZE - 1 : 0] DAT_I,
+ output wire [8*WORD_SIZE - 1 : 0] DAT_O,
+ /* input wire [GRANULARITY - 1 : 0] SEL_I, */ /* we'll use that soon */
+ input wire RST_I,
+ input wire STB_I,
+ input wire WE_I,
+ output wire STALL_O
);
/*
@@ -33,37 +38,52 @@ module memory_slave_model
* WARNING! The 'memory' variable might be referenced from outside the module
* by testbench code - be careful when changing or removing it
*/
- reg [15:0] memory [2**18 - 1 : 0];
+ reg [8*WORD_SIZE - 1 : 0] memory [2**ADR_BITS - 1 : 0];
- integer seed; /* For random stall times and acknowledge times */
+ /* For random stall times and acknowledge times */
+ integer seed;
parameter MAX_STALL_TIME = 7;
parameter MAX_ACK_WAIT_TIME = 7;
- reg [2:0] stall_time_left;
- reg [2:0] acknowledge_time_left;
+ reg [2:0] stall_time_left;
+ reg [2:0] acknowledge_time_left;
- /*
- * Bit 34 contains latched WE_I; bits 33:16 contain latched ADR_I;
- * bits 15:0 contain latched DAT_I
- */
- reg [34:0] command_pipeline [15:0];
- reg [3:0] pipeline_oldest_element;
- reg [4:0] pipeline_elements_count;
- wire [3:0] pipeline_index_to_insert;
+ /* incoming command pipeline */
+ reg WE_I_pipeline [15:0];
+ reg [ADR_BITS - 1 : 0] ADR_I_pipeline [15:0];
+ reg [8*WORD_SIZE - 1 : 0] DAT_I_pipeline [15:0];
+
+ reg [3:0] pipeline_oldest_element;
+ reg [4:0] pipeline_elements_count;
+ wire [3:0] pipeline_index_to_insert;
assign pipeline_index_to_insert = (pipeline_oldest_element +
pipeline_elements_count) % 16;
- reg stall;
+ reg stall;
+
+ reg WE_I_to_process;
+ reg [ADR_BITS - 1 : 0] ADR_I_to_process;
+ reg [8*WORD_SIZE - 1 : 0] DAT_I_to_process;
+
+ always @* begin
+ if (pipeline_elements_count) begin
+ WE_I_to_process = WE_I_pipeline[pipeline_oldest_element];
+ ADR_I_to_process = ADR_I_pipeline[pipeline_oldest_element];
+ DAT_I_to_process = DAT_I_pipeline[pipeline_oldest_element];
+ end else begin
+ WE_I_to_process = WE_I;
+ ADR_I_to_process = ADR_I;
+ DAT_I_to_process = DAT_I;
+ end
+ end // always @ *
/* Those are irrelevant if RST_I is high */
- wire pipeline_space_left;
- wire can_accept;
- wire new_command_accepted;
- wire command_available_for_acknowledging;
- wire command_acknowledged;
- wire [34:0] incoming_command;
- wire [34:0] command_to_process;
+ wire pipeline_space_left;
+ wire can_accept;
+ wire new_command_accepted;
+ wire command_available_for_acknowledging;
+ wire command_acknowledged;
assign pipeline_space_left = pipeline_elements_count < 16;
assign can_accept = pipeline_space_left && stall_time_left == 0;
@@ -72,20 +92,13 @@ module memory_slave_model
new_command_accepted;
assign command_acknowledged = acknowledge_time_left == 0 &&
command_available_for_acknowledging;
- assign incoming_command = STB_I ? {WE_I, ADR_I, DAT_I} : 35'bx;
- assign command_to_process = pipeline_elements_count ?
- command_pipeline[pipeline_oldest_element] :
- incoming_command;
- /* Finally, drive the outputs */
- /*
- * command_to_process[34] is low when it's a read command; only drive data
- * outputs for read commands
- */
- assign DAT_O = (command_acknowledged && !command_to_process[34]) ?
- memory[command_to_process[33:16]] : 16'bx;
+ /* Finally, drive the outputs */
+ /* only drive data outputs for read commands */
+ assign DAT_O = (command_acknowledged && !WE_I_to_process) ?
+ memory[ADR_I_to_process] : 16'bx;
assign STALL_O = !can_accept;
@@ -109,7 +122,9 @@ module memory_slave_model
end else begin
if (new_command_accepted) begin
stall_time_left <= $urandom(seed) % (MAX_STALL_TIME + 1);
- command_pipeline[pipeline_index_to_insert] = incoming_command;
+ WE_I_pipeline[pipeline_index_to_insert] <= WE_I;
+ ADR_I_pipeline[pipeline_index_to_insert] <= ADR_I;
+ DAT_I_pipeline[pipeline_index_to_insert] <= DAT_I;
end else begin
if (stall_time_left)
stall_time_left <= stall_time_left - 1;
@@ -119,19 +134,19 @@ module memory_slave_model
acknowledge_time_left <= $urandom(seed) % (MAX_ACK_WAIT_TIME + 1);
pipeline_oldest_element <= pipeline_oldest_element + 1;
- if (command_to_process[34]) begin /* Write command */
+ if (WE_I_to_process) begin /* Write command */
if (WRITABLE) begin
- memory[command_to_process[33:16]] <= command_to_process[15:0];
+ memory[ADR_I_to_process] <= DAT_I_to_process;
`DBG(("Slave %0d: write of h%x at h%x", SLAVE_NR,
- command_to_process[15:0], command_to_process[31:16]));
+ DAT_I_to_process, ADR_I_to_process));
end else begin
`DBG(({"Slave %0d: error: write of h%x at h%x ",
"(read-only) memory"}, SLAVE_NR,
- command_to_process[15:0], command_to_process[31:16]));
+ DAT_I_to_process, ADR_I_to_process));
end
end else begin /* Read command */
`DBG(("Slave %0d: read of h%x at h%x", SLAVE_NR,
- DAT_O, command_to_process[31:16]));
+ DAT_O, ADR_I_to_process));
end
end else if (command_available_for_acknowledging) begin
acknowledge_time_left <= acknowledge_time_left - 1;