[11] | 1 | module DIRECTORY( |
---|
| 2 | clk, |
---|
| 3 | write_back_req1, inval1, // output: requests from directory |
---|
| 4 | write_back_req2, inval2, // output: requests from directory |
---|
| 5 | blocknum, // output: requests from directory |
---|
| 6 | blk_ok1, blk_data, // output: answers from directory |
---|
| 7 | blk_ok2, // output: answers from directory |
---|
| 8 | back_data1, cache_req1, blk_add1, // input: to directory |
---|
| 9 | back_data2, cache_req2, blk_add2); // input: to directory |
---|
| 10 | |
---|
| 11 | |
---|
| 12 | input clk; |
---|
| 13 | output [`address_size:0] blocknum; // output: requests from directory |
---|
| 14 | output write_back_req1, inval1; // output: requests from directory |
---|
| 15 | output blk_ok1; // output: answers from directory |
---|
| 16 | output blk_data; |
---|
| 17 | input back_data1; // input: to directory |
---|
| 18 | output write_back_req2, inval2; // output: requests from directory |
---|
| 19 | output blk_ok2; // output: answers from directory |
---|
| 20 | input back_data2; // input: to directory |
---|
| 21 | input [`address_size:0] blk_add1; // input: to directory |
---|
| 22 | input [`address_size:0] blk_add2; // input: to directory |
---|
| 23 | input cache_req1; // input to directory |
---|
| 24 | input cache_req2; // input to directory |
---|
| 25 | |
---|
| 26 | reg main_mem [`mem_size:0]; |
---|
| 27 | reg cache_Rlist1 [`mem_size:0]; |
---|
| 28 | reg cache_Rlist2 [`mem_size:0]; |
---|
| 29 | |
---|
| 30 | reg cache_Wlist1 [`mem_size:0]; |
---|
| 31 | reg cache_Wlist2 [`mem_size:0]; |
---|
| 32 | |
---|
| 33 | wire blk_data; |
---|
| 34 | wire write_back_req1; |
---|
| 35 | wire write_back_req2; |
---|
| 36 | |
---|
| 37 | wire blk_ok1; |
---|
| 38 | wire blk_ok2; |
---|
| 39 | |
---|
| 40 | wire inval1; |
---|
| 41 | wire inval2; |
---|
| 42 | |
---|
| 43 | wire [`address_size:0] blocknum; |
---|
| 44 | |
---|
| 45 | Cache_reqstatus wire cache_req1; |
---|
| 46 | Cache_reqstatus wire cache_req2; |
---|
| 47 | |
---|
| 48 | |
---|
| 49 | Arbiter_status reg arbiter_state; |
---|
| 50 | |
---|
| 51 | initial begin |
---|
| 52 | arbiter_state = ONE; |
---|
| 53 | // initialize all memory |
---|
| 54 | for (i=0; i<=`mem_size; i =i+1) |
---|
| 55 | begin |
---|
| 56 | main_mem[i] =0; |
---|
| 57 | cache_Rlist1[i]=0; |
---|
| 58 | cache_Rlist2[i]=0; |
---|
| 59 | cache_Wlist1[i]=0; |
---|
| 60 | cache_Wlist2[i]=0; |
---|
| 61 | end |
---|
| 62 | end |
---|
| 63 | |
---|
| 64 | assign inval1 = ((arbiter_state==TWO)&&(cache_req2==blk_excl))?1:0; |
---|
| 65 | assign inval2 = ((arbiter_state==ONE)&&(cache_req1==blk_excl))?1:0; |
---|
| 66 | assign write_back_req1 = ((arbiter_state==TWOWAIT)&&(cache_req1 != ok))?1:0; |
---|
| 67 | assign write_back_req2 = ((arbiter_state==ONEWAIT)&&(cache_req2 != ok))?1:0; |
---|
| 68 | assign blk_data = (arbiter_state==ONESERVE) ? main_mem[blk_add1]: |
---|
| 69 | (arbiter_state==TWOSERVE) ? main_mem[blk_add2]: 0; |
---|
| 70 | assign blk_ok1 = (arbiter_state==ONESERVE) ? 1:0; |
---|
| 71 | assign blk_ok2 = (arbiter_state==TWOSERVE) ? 1:0; |
---|
| 72 | assign blocknum = ((arbiter_state==ONE)&&(cache_req1==blk_excl))? |
---|
| 73 | blk_add1: |
---|
| 74 | ((arbiter_state==TWO)&&(cache_req2==blk_excl))? |
---|
| 75 | blk_add2:0; |
---|
| 76 | |
---|
| 77 | always @(posedge clk) begin |
---|
| 78 | |
---|
| 79 | // Ok now I put in the arbiter |
---|
| 80 | // a one clock cycle delay |
---|
| 81 | // asumption a cc will not put down its request until serviced |
---|
| 82 | |
---|
| 83 | case ( arbiter_state ) |
---|
| 84 | ONE: begin |
---|
| 85 | if (cache_req1 == blk_rreq) |
---|
| 86 | begin |
---|
| 87 | if (cache_Wlist2[blk_add1]==1) |
---|
| 88 | // one requests a read and someone has that address in wx |
---|
| 89 | begin |
---|
| 90 | cache_Rlist1[blk_add1] = 1; |
---|
| 91 | // The processor that returned the data is no longer in write X |
---|
| 92 | cache_Wlist2[blk_add1] = 0; |
---|
| 93 | cache_Rlist2[blk_add1] = 1; |
---|
| 94 | arbiter_state = ONEWAIT; |
---|
| 95 | end |
---|
| 96 | else |
---|
| 97 | begin |
---|
| 98 | //one request a read and non-one has the address in wx |
---|
| 99 | // any block in write access overwritten in cache1 |
---|
| 100 | // remove all address from Wlist1 |
---|
| 101 | for (i=0; i<=`mem_size; i =i+1) |
---|
| 102 | begin |
---|
| 103 | cache_Wlist1[i]=0; |
---|
| 104 | end |
---|
| 105 | cache_Rlist1[blk_add1] = 1; |
---|
| 106 | arbiter_state = ONESERVE; |
---|
| 107 | end |
---|
| 108 | end |
---|
| 109 | // one requests a write |
---|
| 110 | else if (cache_req1 == blk_excl) |
---|
| 111 | begin |
---|
| 112 | cache_Wlist1[blk_add1] = 1; |
---|
| 113 | cache_Rlist1[blk_add1] = 0; |
---|
| 114 | cache_Rlist2[blk_add1] = 0; |
---|
| 115 | cache_Wlist2[blk_add1] = 0; |
---|
| 116 | arbiter_state = ONESERVE; |
---|
| 117 | end |
---|
| 118 | else |
---|
| 119 | begin |
---|
| 120 | arbiter_state = TWO; |
---|
| 121 | end |
---|
| 122 | end |
---|
| 123 | |
---|
| 124 | // servicing a request from cache 1 |
---|
| 125 | |
---|
| 126 | ONESERVE: arbiter_state = TWO; |
---|
| 127 | |
---|
| 128 | // waiting for write_back from cache 2 |
---|
| 129 | |
---|
| 130 | |
---|
| 131 | ONEWAIT: begin |
---|
| 132 | if (cache_req2 == ok) |
---|
| 133 | // if the processor has just returned data which it was asked for |
---|
| 134 | // update memory if write ex clcache |
---|
| 135 | begin |
---|
| 136 | main_mem[blk_add1] = back_data2; |
---|
| 137 | arbiter_state = ONESERVE; |
---|
| 138 | end |
---|
| 139 | end |
---|
| 140 | // |
---|
| 141 | // Symmetric statements for TWO |
---|
| 142 | // |
---|
| 143 | TWO: begin |
---|
| 144 | if (cache_req2 == blk_rreq) |
---|
| 145 | begin |
---|
| 146 | if (cache_Wlist1[blk_add2]==1) |
---|
| 147 | // TWO requests a read and someone has that address in wx |
---|
| 148 | begin |
---|
| 149 | cache_Rlist2[blk_add2] = 1; |
---|
| 150 | // The processor that returned the data is no longer in write X |
---|
| 151 | cache_Wlist1[blk_add2] = 0; |
---|
| 152 | cache_Rlist1[blk_add2] = 1; |
---|
| 153 | arbiter_state = TWOWAIT; |
---|
| 154 | end |
---|
| 155 | else |
---|
| 156 | begin |
---|
| 157 | //TWO request a read and non-one has the address in wx |
---|
| 158 | // any block in write access overwritten in cache1 |
---|
| 159 | // remove all address from Wlist2 |
---|
| 160 | for (i=0; i<=`mem_size; i =i+1) |
---|
| 161 | begin |
---|
| 162 | cache_Wlist2[i]=0; |
---|
| 163 | end |
---|
| 164 | cache_Rlist2[blk_add2] = 1; |
---|
| 165 | arbiter_state = TWOSERVE; |
---|
| 166 | end |
---|
| 167 | end |
---|
| 168 | // two requests a write |
---|
| 169 | else if (cache_req2 == blk_excl) |
---|
| 170 | begin |
---|
| 171 | // blocknum = blk_add2; |
---|
| 172 | cache_Wlist1[blk_add2] = 0; |
---|
| 173 | cache_Rlist1[blk_add2] = 0; |
---|
| 174 | cache_Rlist2[blk_add2] = 0; |
---|
| 175 | cache_Wlist2[blk_add2] = 1; |
---|
| 176 | arbiter_state = TWOSERVE; |
---|
| 177 | end |
---|
| 178 | else |
---|
| 179 | begin |
---|
| 180 | arbiter_state = ONE; |
---|
| 181 | end |
---|
| 182 | end |
---|
| 183 | |
---|
| 184 | // servicing a request from cache 2 |
---|
| 185 | |
---|
| 186 | TWOSERVE: arbiter_state = ONE; |
---|
| 187 | |
---|
| 188 | // if waiting for write_back |
---|
| 189 | |
---|
| 190 | |
---|
| 191 | TWOWAIT: begin |
---|
| 192 | // if the processor has just returned data which it was asked for |
---|
| 193 | // update memory if write ex clcache |
---|
| 194 | if (cache_req1 == ok) |
---|
| 195 | begin |
---|
| 196 | main_mem[blk_add2] = back_data1; |
---|
| 197 | arbiter_state = TWOSERVE; |
---|
| 198 | end |
---|
| 199 | end |
---|
| 200 | default:; |
---|
| 201 | endcase; |
---|
| 202 | end |
---|
| 203 | endmodule |
---|
| 204 | |
---|
| 205 | |
---|
| 206 | |
---|
| 207 | |
---|