diff options
Diffstat (limited to 'models')
-rw-r--r-- | models/slave.v | 107 |
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; |