|
|
1 //+++++++++++++++++++++++++++++++++++++++++++++++++
2 // Define the interface
3 //+++++++++++++++++++++++++++++++++++++++++++++++++
4 interface mem_if (input wire clk);
5 logic reset;
6 logic we_sys;
7 logic cmd_valid_sys;
8 logic ready_sys;
9 logic [7:0] data_sys;
10 logic [7:0] addr_sys;
11 logic we_mem;
12 logic ce_mem;
13 logic [7:0] datao_mem;
14 logic [7:0] datai_mem;
15 logic [7:0] addr_mem;
16 //=================================================
17 // Modport for System interface
18 //=================================================
19 modport system (input clk,reset,we_sys, cmd_valid_sys,
20 addr_sys, datao_mem,
21 output we_mem, ce_mem, addr_mem,
22 datai_mem, ready_sys, ref data_sys);
23 //=================================================
24 // Modport for memory interface
25 //=================================================
26 modport memory (input clk,reset,we_mem, ce_mem,
27 addr_mem, datai_mem, output datao_mem);
28 //=================================================
29 // Modport for testbench
30 //=================================================
31 modport tb (input clk, ready_sys,
32 output reset,we_sys, cmd_valid_sys, addr_sys,
33 ref data_sys);
34
35 endinterface
36
37 //+++++++++++++++++++++++++++++++++++++++++++++++++
38 // Memory Model
39 //+++++++++++++++++++++++++++++++++++++++++++++++++
40 module memory_model (mem_if.memory mif);
41 // Memory array
42 logic [7:0] mem [0:255];
43
44 //=================================================
45 // Write Logic
46 //=================================================
47 always @ (posedge mif.clk)
48 if (mif.ce_mem && mif.we_mem) begin
49 mem[mif.addr_mem] <= mif.datai_mem;
50 end
51
52 //=================================================
53 // Read Logic
54 //=================================================
55 always @ (posedge mif.clk)
56 if (mif.ce_mem && ~mif.we_mem) begin
57 mif.datao_mem <= mem[mif.addr_mem];
58 end
59
60 endmodule
61
62 //+++++++++++++++++++++++++++++++++++++++++++++++++
63 // Memory Controller
64 //+++++++++++++++++++++++++++++++++++++++++++++++++
65 module memory_ctrl (mem_if.system sif);
66
67 typedef enum {IDLE,WRITE,READ,DONE} fsm_t;
68
69 fsm_t state;
70
71 always @ (posedge sif.clk)
72 if (sif.reset) begin
73 state <= IDLE;
74 sif.ready_sys <= 0;
75 sif.we_mem <= 0;
76 sif.ce_mem <= 0;
77 sif.addr_mem <= 0;
78 sif.datai_mem <= 0;
79 sif.data_sys <= 8'bz;
80 end else begin
81 case(state)
82 IDLE : begin
83 sif.ready_sys <= 1'b0;
84 if (sif.cmd_valid_sys && sif.we_sys) begin
85 sif.addr_mem <= sif.addr_sys;
86 sif.datai_mem <= sif.data_sys;
87 sif.we_mem <= 1'b1;
88 sif.ce_mem <= 1'b1;
89 state <= WRITE;
90 end
91 if (sif.cmd_valid_sys && ~sif.we_sys) begin
92 sif.addr_mem <= sif.addr_sys;
93 sif.datai_mem <= sif.data_sys;
94 sif.we_mem <= 1'b0;
95 sif.ce_mem <= 1'b1;
96 state <= READ;
97 end
98 end
99 WRITE : begin
100 sif.ready_sys <= 1'b1;
101 if (~sif.cmd_valid_sys) begin
102 sif.addr_mem <= 8'b0;
103 sif.datai_mem <= 8'b0;
104 sif.we_mem <= 1'b0;
105 sif.ce_mem <= 1'b0;
106 state <= IDLE;
107 end
108 end
109 READ : begin
110 sif.ready_sys <= 1'b1;
111 sif.data_sys <= sif.datao_mem;
112 if (~sif.cmd_valid_sys) begin
113 sif.addr_mem <= 8'b0;
114 sif.datai_mem <= 8'b0;
115 sif.we_mem <= 1'b0;
116 sif.ce_mem <= 1'b0;
117 sif.ready_sys <= 1'b1;
118 state <= IDLE;
119 sif.data_sys <= 8'bz;
120 end
121 end
122 endcase
123 end
124
125 endmodule
126
127 //+++++++++++++++++++++++++++++++++++++++++++++++++
128 // Test program
129 //+++++++++++++++++++++++++++++++++++++++++++++++++
130 program test(mem_if.tb tif);
131
132 initial begin
133 tif.reset <= 1;
134 tif.we_sys <= 0;
135 tif.cmd_valid_sys <= 0;
136 tif.addr_sys <= 0;
137 tif.data_sys <= 8'bz;
138 #100 tif.reset <= 0;
139 for (int i = 0; i < 4; i ++) begin
140 @ (posedge tif.clk);
141 tif.addr_sys <= i;
142 tif.data_sys <= $random;
143 tif.cmd_valid_sys <= 1;
144 tif.we_sys <= 1;
145 @ (posedge tif.ready_sys);
146 $display("@%0dns Writing address %0d with data %0x",
147 $time, i,tif.data_sys);
148 @ (posedge tif.clk);
149 tif.addr_sys <= 0;
150 tif.data_sys <= 8'bz;
151 tif.cmd_valid_sys <= 0;
152 tif.we_sys <= 0;
153 end
154 repeat (10) @ (posedge tif.clk);
155 for (int i= 0; i < 4; i ++) begin
156 @ (posedge tif.clk);
157 tif.addr_sys <= i;
158 tif.cmd_valid_sys <= 1;
159 tif.we_sys <= 0;
160 @ (posedge tif.ready_sys);
161 @ (posedge tif.clk);
162 $display("@%0dns Reading address %0d, Got data %0x",
163 $time, i,tif.data_sys);
164 tif.addr_sys <= 0;
165 tif.cmd_valid_sys <= 0;
166 end
167 #10 $finish;
168 end
169
170 endprogram
171
172 //+++++++++++++++++++++++++++++++++++++++++++++++++
173 // Testbench
174 //+++++++++++++++++++++++++++++++++++++++++++++++++
175 module interface_modports();
176
177 logic clk = 0;
178 always #10 clk++;
179 //=================================================
180 // Instianciate Interface and DUT
181 //=================================================
182 mem_if miff(clk);
183 memory_ctrl U_ctrl(miff);
184 memory_model U_model(miff);
185 test U_test(miff);
186
187 endmodule
You could download file interface_modports.sv here
|
|
|
@150ns Writing address 0 with data 24
@230ns Writing address 1 with data 81
@310ns Writing address 2 with data 9
@390ns Writing address 3 with data 63
@690ns Reading address 0, Got data 24
@770ns Reading address 1, Got data 81
@850ns Reading address 2, Got data 9
@930ns Reading address 3, Got data 63
|