-
Notifications
You must be signed in to change notification settings - Fork 3
/
mem.sv
131 lines (114 loc) · 2.88 KB
/
mem.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// -*- mode: Verilog; fill-column: 90 -*-
//
// Hacked up memory for testing
`timescale 1 ns / 1 ns
`include "constants.svh"
module mem
(
input clk,
input reset,
input [`PADDR] mem_addr,
output reg [`WORD] mem_read_data,
input [`WORD] mem_write_data,
input mem_read,
input mem_write,
output reg read_ack,
output reg write_ack
);
reg [`WORD] ram[0:2**`PADDRSIZE-1];
reg [30*8:1] filename;
reg read_ip, write_ip, rw_done;
reg [`PADDR] saved_addr;
reg [`WORD] saved_write_data;
reg [0:4] wait_count;
localparam wait_time = 0;
initial begin
`ifndef LINT
if (! $value$plusargs("file=%s", filename)) begin
$display("ERROR: please specify +file=<filename> to start.");
$finish_and_return(10);
end
`endif
$readmemh(filename, ram);
read_ip = 0;
write_ip = 0;
rw_done = 0;
wait_count = 0;
end
// hack for pushing the acks immediately so they're there a cycle earlier than the data.
// only works if wait_time is 0.
//`define IACK 1
`ifdef IACK
always @(*) read_ack = mem_read;
always @(*) write_ack = mem_write;
`endif
always @(posedge clk) begin
`ifndef IACK
write_ack <= 0;
read_ack <= 0;
`endif
if (wait_count != 0)
wait_count <= wait_count - 1;
else if (rw_done) begin
$display("done");
rw_done <= 0;
end else begin
if (read_ip) begin
//`define DEBUG_MEM
`ifdef DEBUG_MEM
$display(" <-- [%06o]", mem_addr);
`endif
mem_read_data <= ram[saved_addr];
// read_ack <= 1;
read_ip <= 0;
end else if (write_ip) begin
`ifdef DEBUG_MEM
$display(" [%06o] <-- %06o,%06o", saved_addr, saved_write_data[0:17], saved_write_data[18:35]);
`endif
ram[saved_addr] <= saved_write_data;
`ifndef IACK
write_ack <= 1;
`endif
write_ip <= 0;
end
if (mem_read) begin
`ifdef DEBUG_MEM
$write("Reading ");
`endif
if (wait_time == 0) begin
`ifdef DEBUG_MEM
$display(" <-- [%06o]", mem_addr);
`endif
mem_read_data <= ram[mem_addr];
`ifndef IACK
read_ack <= 1;
`endif
rw_done <= 0;
end else begin
saved_addr <= mem_addr;
read_ip <= 1;
wait_count <= wait_time - 1;
end
end else if (mem_write) begin // if (mem_read)
`ifdef DEBUG_MEM
$write("Writing ");
`endif
if (wait_time == 0) begin
`ifdef DEBUG_MEM
$display(" [%06o] <-- %06o,%06o", mem_addr, mem_write_data[0:17], mem_write_data[18:35]);
`endif
ram[mem_addr] <= mem_write_data;
`ifndef IACK
write_ack <= 1;
`endif
rw_done <= 0;
end else begin
saved_addr <= mem_addr;
saved_write_data <= mem_write_data;
write_ip <= 1;
wait_count <= wait_time - 1;
end // else: !if(wait_time == 0)
end
end
end
endmodule // mem