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