aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/macroasm.vh13
-rw-r--r--models/master.v168
2 files changed, 104 insertions, 77 deletions
diff --git a/include/macroasm.vh b/include/macroasm.vh
index 0c63ea7..e6a2893 100644
--- a/include/macroasm.vh
+++ b/include/macroasm.vh
@@ -22,12 +22,7 @@ operations:
3 - deselect (CYC_O low for one tick)
))
-`define READ(addr, expected_data) 0``addr``expected_data
-`define WRITE(addr, data) 1``addr``data
-`define WAIT 2xxxxxxxxx
-`define DESELECT 3xxxxxxxxx
-
-`C((
-We have to take care to use the correct number of digits for addresses and
-datas - the macros don't validate their arguments!
-))
+`define READ(addr, expected_data) 0 addr expected_data
+`define WRITE(addr, data) 1 addr data
+`define WAIT 2 x x
+`define DESELECT 3 x x
diff --git a/models/master.v b/models/master.v
index 0e128ec..5c8bacf 100644
--- a/models/master.v
+++ b/models/master.v
@@ -1,4 +1,10 @@
-/* A wishbone slave testing module (a "mock") */
+/*
+ * A wishbone slave testing module (a "mock")
+ *
+ * It performs a sequence of wishbone writes, reads and waits based on contents
+ * of provided .mem file. It prints error messages whenever the value it reads
+ * if different from the one it expects.
+ */
`default_nettype none
`include "messages.vh"
@@ -11,95 +17,111 @@
module master_model
#(
parameter MASTER_NR = -1,
+ parameter WORD_SIZE = 2, /* in bytes */
+ parameter GRANULARITY = 2, /* in bytes */ /* we'll use that soon */
+ parameter ADR_BITS = 20,
parameter OPERATIONS_FILE = "master_operations.mem",
parameter OPERATIONS_COUNT = 10
)
(
- input wire ACK_I,
- input wire CLK_I,
- output wire [19:0] ADR_O,
- input wire [15:0] DAT_I,
- output wire [15:0] DAT_O,
- input wire RST_I,
- output wire STB_O,
- output wire CYC_O,
- output wire WE_O,
- input wire STALL_I,
+ input wire ACK_I,
+ input wire CLK_I,
+ output wire [ADR_BITS - 1 : 0] ADR_O,
+ input wire [8*WORD_SIZE - 1 : 0] DAT_I,
+ output wire [8*WORD_SIZE - 1 : 0] DAT_O,
+ /* output wire [GRANULARITY - 1 : 0] SEL_O, */ /* we'll use that soon */
+ input wire RST_I,
+ output wire STB_O,
+ output wire CYC_O,
+ output wire WE_O,
+ input wire STALL_I,
/* Non-wishbone */
- output wire finished
+ output wire finished
);
+ parameter WORD_BITS = 8 * WORD_SIZE;
+
parameter
OP_READ = 0,
OP_WRITE = 1,
OP_WAIT = 2, /* Keep CYC_O high, but STB_O low for 1 tick */
OP_DESELECT = 3; /* Drive CYC_O low for one tick */
- /*
- * Bits 39:36 specify type of the operation; bits 35:16 contain the
- * address for read wnd write operations (may contain garbage otherwise);
- * bits 15:0 contain data to write (for write operation) or expected data
- * (for read operation) or are irrelevant (for other operations)
- */
- reg [39:0] operations [OPERATIONS_COUNT - 1 : 0];
+ /* See below what we need this for */
+ parameter BIGGEST_WIDTH = ADR_BITS > WORD_BITS ? ADR_BITS : WORD_BITS;
/*
- * This will allow us to check whether read operation returned proper data;
- * bit 16 tells us whether the corresponding command was a read; if not,
- * bits 15:0 don't matter; if yes bits 15:0 contain the data we should
- * receive from that read operation
+ * Contents of this array determine, what this master will do.
+ * Each (3*n)th element denotes type of operation number n.
+ * (3*n+1)th element denotes address to use and (3*n+2)th element denotes
+ * data to use
*/
- reg [16:0] expected_results [OPERATIONS_COUNT - 1 : 0];
+ reg [BIGGEST_WIDTH - 1 : 0] operations [3*OPERATIONS_COUNT - 1 : 0];
- integer i, j;
+ /* Arrays used for verifying read reaults */
+ reg was_read [OPERATIONS_COUNT - 1 : 0];
+ reg [WORD_BITS - 1 : 0] expected_data [OPERATIONS_COUNT - 1 : 0];
+
+ integer i, j;
initial begin
- $readmemh(OPERATIONS_FILE, operations, 0, OPERATIONS_COUNT - 1);
+ $readmemh(OPERATIONS_FILE, operations, 0, 3*OPERATIONS_COUNT - 1);
j = 0;
for (i = 0; i < OPERATIONS_COUNT; i++) begin
- if (operations[i][39:36] == OP_READ ||
- operations[i][39:36] == OP_WRITE) begin
- if (operations[i][39:36] == OP_READ)
- expected_results[j] <= {1'b1, operations[i][15:0]};
- else
- expected_results[j] <= {1'b0, 16'bx};
+ if (operations[3*i][1:0] == OP_READ) begin
+ was_read[j] <= 1;
+ expected_data[j] <= operations[3*i + 2][WORD_BITS - 1 : 0];
j++;
end
- end
- end
+
+ if (operations[3*i][1:0] == OP_WRITE) begin
+ was_read[j] <= 0;
+ expected_data[j] <= {(8 * WORD_SIZE - 1){1'bx}};
- reg [31:0] operations_performed;
- reg [31:0] commands_sent;
- reg [31:0] commands_acknowledged;
+ j++;
+ end
+ end // for (i = 0; i < OPERATIONS_COUNT; i++)
+ end // initial begin
+
+ reg [31:0] operations_performed;
+ reg [31:0] commands_sent;
+ reg [31:0] commands_acknowledged;
/* Those are irrelevant if RST_I is high */
- wire command_successful;
- wire wait_successful;
- wire deselect_successful;
- wire [2:0] current_operation_type;
- wire operation_successful;
- wire [31:0] operations_performed_next_tick;
- wire [39:0] operation_to_perform;
- wire acknowledgement_successful;
- wire [31:0] commands_sent_next_tick;
- wire [31:0] commands_acknowledged_next_tick;
- wire [31:0] acknowledgements_needed;
+ wire command_successful;
+ wire wait_successful;
+ wire deselect_successful;
+ wire [1:0] current_op_type;
+ wire [ADR_BITS - 1 : 0] current_op_adr;
+ wire [WORD_BITS - 1 : 0] current_op_data;
+ wire operation_successful;
+ wire [31:0] operations_performed_next_tick;
+ wire acknowledgement_successful;
+ wire [31:0] commands_sent_next_tick;
+ wire [31:0] commands_acknowledged_next_tick;
+ wire [31:0] acknowledgements_needed;
assign command_successful = CYC_O && STB_O && !STALL_I;
assign wait_successful = !STB_O && !STALL_I;
assign deselect_successful = !CYC_O;
- assign current_operation_type = operations[operations_performed][39:36];
+
+ assign current_op_type
+ = operations[3*operations_performed][1:0];
+ assign current_op_adr
+ = operations[3*operations_performed + 1][ADR_BITS - 1 : 0];
+ assign current_op_data
+ = operations[3*operations_performed + 2][WORD_BITS - 1 : 0];
+
assign operation_successful
= operations_performed < OPERATIONS_COUNT &&
- ((current_operation_type == OP_READ && command_successful) ||
- (current_operation_type == OP_WRITE && command_successful) ||
- (current_operation_type == OP_WAIT && wait_successful) ||
- (current_operation_type == OP_DESELECT && deselect_successful));
+ ((current_op_type == OP_READ && command_successful) ||
+ (current_op_type == OP_WRITE && command_successful) ||
+ (current_op_type == OP_WAIT && wait_successful) ||
+ (current_op_type == OP_DESELECT && deselect_successful));
assign operations_performed_next_tick
= operations_performed + operation_successful;
- assign operation_to_perform = operations[operations_performed_next_tick];
assign commands_sent_next_tick = commands_sent + command_successful;
assign acknowledgement_successful
@@ -109,6 +131,18 @@ module master_model
assign acknowledgements_needed
= commands_sent_next_tick - commands_acknowledged_next_tick;
+ wire [31:0] idx_to_use;
+ wire [1:0] next_op_type;
+ wire [ADR_BITS - 1 : 0] next_op_adr;
+ wire [WORD_BITS - 1 : 0] next_op_data;
+
+ assign idx_to_use = operations_performed_next_tick;
+ assign next_op_type = operations[3*idx_to_use][1:0];
+ assign next_op_adr = operations[3*idx_to_use + 1][ADR_BITS - 1 : 0];
+ assign next_op_data = operations[3*idx_to_use + 2][WORD_BITS - 1 : 0];
+
+ /* Drive the outputs */
+
reg strobe;
assign STB_O = strobe;
@@ -147,23 +181,22 @@ module master_model
end else begin
/* debug messages */
if (command_successful) begin
- case (current_operation_type)
+ case (current_op_type)
OP_READ : begin
`DBG(("Master %0d: sent read command at h%x", MASTER_NR,
- operations[operations_performed][35:16]));
+ current_op_adr));
end
OP_WRITE : begin
`DBG(("Master %0d: sent write command of h%x at h%x",
- MASTER_NR, operations[operations_performed][15:0],
- operations[operations_performed][35:16]));
+ MASTER_NR, current_op_data, current_op_adr));
end
default :
`MSG(("Master %0d: error: bug in test bench", MASTER_NR));
- endcase // case (current_operation_type)
+ endcase // case (current_op_type)
end // if (command_successful)
if (acknowledgement_successful) begin
- if (expected_results[commands_acknowledged][16])
+ if (was_read[commands_acknowledged])
`DBG(("Master %0d: acknowledged read of h%x", MASTER_NR, DAT_I));
else
`DBG(("Master %0d: acknowledged write", MASTER_NR));
@@ -183,19 +216,19 @@ module master_model
end else begin
operations_performed <= operations_performed_next_tick;
- case (operation_to_perform[39:36])
+ case (next_op_type)
OP_READ : begin
cycle <= 1;
strobe <= 1;
write_enable <= 0;
- addr <= operation_to_perform[35:16];
+ addr <= next_op_adr;
end
OP_WRITE : begin
cycle <= 1;
strobe <= 1;
write_enable <= 1;
- addr <= operation_to_perform[35:16];
- output_data <= operation_to_perform[15:0];
+ addr <= next_op_adr;
+ output_data <= next_op_data;
end
OP_WAIT : begin
cycle <= 1;
@@ -209,11 +242,10 @@ module master_model
end // else: !if(operations_performed_next_tick == OPERATIONS_COUNT)
if (acknowledgement_successful) begin
- if (expected_results[commands_acknowledged][15:0] !== DAT_I &&
- expected_results[commands_acknowledged][16]) begin
+ if (expected_data[commands_acknowledged] !== DAT_I &&
+ was_read[commands_acknowledged]) begin
`MSG(("Master %0d: error: read h%x instead of h%x",
- MASTER_NR, DAT_I,
- expected_results[commands_acknowledged][15:0]));
+ MASTER_NR, DAT_I, expected_data[commands_acknowledged]));
end
end
end // else: !if(RST_I)