00001 extern "C" {
00002
00003 #include "tarski.h"
00004
00005
00006 array_t *
00007 build_double_instr()
00008 {
00009 array_t *result_array = array_alloc(Fnode *, 0);
00010
00011 F instr_data_reg1 = sr("double_instr_data_reg1");
00012 F instr_data_reg2 = sr("double_instr_data_reg2");
00013 F instr_data1 = si("instr_data1");
00014 F instr_data2 = si("instr_data2");
00015 F instr_data = si("instr_data");
00016
00017 F instr_valid = br("double_instr_valid");
00018 F instr_valid2 = br("double_instr_valid2");
00019
00020 F LD = sc("LD");
00021
00022 F regfile = sr("mem@doubleRF");
00023 F init_regfile = si("initRF");
00024 F instr_buffer_valid = br("double_instr_buffer_valid");
00025 F instr_buffer = sr("double_instr_buffer");
00026 F init_instr_buffer_valid = FALSE();
00027
00028 F init_instr_buffer = si("init_instr_buffer");
00029
00030 F instr_buffer_load = instr_valid & !instr_buffer_valid;
00031 F next_instr_buffer = mux(instr_buffer_load,
00032 instr_data_reg1,
00033 instr_buffer);
00034 instr_buffer << (init_instr_buffer % next_instr_buffer);
00035
00036 F first_instr = uif("first_instr",
00037 instr_buffer);
00038
00039 F second_instr = uif("second_instr",
00040 instr_buffer);
00041
00042
00043 F first_address1 = uif("src1",
00044 first_instr);
00045 F first_address2 = uif("src2",
00046 first_instr);
00047 F first_arg1 = uif2("mem@read",
00048 regfile,
00049 first_address1);
00050 F first_arg2 = uif2("mem@read",
00051 regfile,
00052 first_address2);
00053 F first_op = uif("op",
00054 first_instr);
00055 F first_alu_result = uif3("alu",
00056 first_op,
00057 first_arg1,
00058 first_arg2);
00059 F first_dest = uif("dest",
00060 first_instr);
00061 F first_load_value = uif("imm",
00062 first_instr);
00063 F first_select_alu = !(first_instr == LD);
00064 F first_result = mux(first_select_alu,
00065 first_alu_result,
00066 first_load_value);
00067
00068
00069 F second_address1 = uif("src1",
00070 second_instr);
00071 F second_address2 = uif("src2",
00072 second_instr);
00073 F second_arg1 = uif2("mem@read",
00074 regfile,
00075 second_address1);
00076 F second_arg2 = uif2("mem@read",
00077 regfile,
00078 second_address2);
00079 F second_op = uif("op",
00080 second_instr);
00081 F second_alu_result = uif3("alu",
00082 second_op,
00083 second_arg1,
00084 second_arg2);
00085 F second_dest = uif("dest",
00086 second_instr);
00087 F second_load_value = uif("imm",
00088 second_instr);
00089 F second_select_alu = !(second_instr == LD);
00090 F second_result = mux(second_select_alu,
00091 second_alu_result,
00092 second_load_value);
00093
00094 F resource_conflict = instr_buffer_valid & ((first_dest == second_dest) | (second_select_alu & ((second_address1 == first_dest) | (second_address2 == first_dest))));
00095
00096 F first_instr_only_committed_last_cycle = br("first_instr_only_committed");
00097
00098 F second_instruction_not_stalled = first_instr_only_committed_last_cycle | (! resource_conflict);
00099
00100 F first_instr_write = instr_buffer_valid & (!first_instr_only_committed_last_cycle);
00101
00102 F second_instr_write = instr_buffer_valid & second_instruction_not_stalled;
00103
00104 F next_first_instr_only_committed_last_cycle = first_instr_write & (!second_instruction_not_stalled);
00105
00106 first_instr_only_committed_last_cycle << (FALSE() % next_first_instr_only_committed_last_cycle);
00107
00108 F next_regfile1 = mux(first_instr_write,
00109 uif3("mem#write",
00110 regfile,
00111 first_dest,
00112 first_result),
00113 regfile);
00114
00115 F next_regfile2 = mux(second_instr_write,
00116 uif3("mem#write",
00117 regfile,
00118 second_dest,
00119 second_result),
00120 next_regfile1);
00121
00122 regfile << (init_regfile % next_regfile2);
00123
00124 F instr_ready = (!instr_buffer_valid);
00125
00126 F next_instr_valid = (instr_ready & instr_valid2) | ((!instr_ready) & instr_valid);
00127 F next_instr_valid2 = (instr_ready & FALSE()) | ((!instr_ready) & instr_valid2);
00128 instr_valid << (TRUE() % next_instr_valid);
00129 instr_valid2 << (FALSE() % next_instr_valid2);
00130
00131 F next_instr_data_reg1 = mux(instr_ready,
00132 instr_data_reg2,
00133 instr_data_reg1);
00134
00135 F next_instr_data_reg2 = mux(instr_ready,
00136 instr_data,
00137 instr_data_reg2);
00138
00139 instr_data_reg1 << (instr_data1 % next_instr_data_reg1);
00140 instr_data_reg2 << (instr_data2 % next_instr_data_reg2);
00141
00142 F instr_committed = br("double_instr_committed");
00143 F next_instr_committed = (second_instr_write | instr_committed);
00144 instr_committed << (FALSE() % next_instr_committed);
00145
00146
00147 F next_instr_buffer_valid = ((instr_ready & instr_valid) | instr_buffer_valid) & (!next_instr_committed);
00148 instr_buffer_valid << (init_instr_buffer_valid % next_instr_buffer_valid);
00149
00150 F arbitrary_read_address = si("read_address");
00151 F regfile_read_data = uif2("mem@read",
00152 regfile,
00153 arbitrary_read_address);
00154 array_insert_last(Fnode*, result_array, instr_ready.raw);
00155 array_insert_last(Fnode*, result_array, instr_committed.raw);
00156 array_insert_last(Fnode*, result_array, regfile_read_data.raw);
00157 return result_array;
00158 }
00159
00160
00161 F
00162 build_microarch_wrapper()
00163 {
00164 array_t *double_array = build_double_instr();
00165 Net_t *double_net;
00166 double_net = Net_CreateFromFormulaArray(double_array);
00167
00168 array_t *single_array = build_single_instr();
00169 Net_t *single_net;
00170 single_net = Net_CreateFromFormulaArray(single_array);
00171
00172 F double_instr_ready;
00173 double_instr_ready.raw = array_fetch(Fnode *, double_array, 0);
00174 F double_instr_committed;
00175 double_instr_committed.raw = array_fetch(Fnode *, double_array, 1);
00176 F double_regfile_data;
00177 double_regfile_data.raw = array_fetch(Fnode *, double_array, 2);
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 F single_instr_ready;
00189 single_instr_ready.raw = array_fetch(Fnode *, single_array, 0);
00190 F single_instr_committed;
00191 single_instr_committed.raw = array_fetch(Fnode *, single_array, 1);
00192 F single_regfile_data;
00193 single_regfile_data.raw = array_fetch(Fnode *, single_array, 2);
00194
00195
00196
00197
00198
00199
00200
00201
00202 F both_instr_committed = double_instr_committed & single_instr_committed;
00203 F regfile_data_different = !(single_regfile_data == double_regfile_data);
00204
00205 F fail_condition = both_instr_committed & regfile_data_different;
00206 Net_t *fail_net = Net_CreateFromFormula(fail_condition.raw);
00207
00208
00209 Net_PrintVHDL(fail_net, 4, "microarch.vhdl", "microarch");
00210 return double_regfile_data;
00211 }
00212
00213 array_t *
00214 build_single_instr()
00215 {
00216 array_t *result_array = array_alloc(Fnode *, 0);
00217
00218 F instr_data_reg1 = sr("single_instr_data_reg1");
00219 F instr_data_reg2 = sr("single_instr_data_reg2");
00220 F instr_data1 = si("instr_data1");
00221 F instr_data2 = si("instr_data2");
00222 F instr_data = si("instr_data");
00223
00224 F instr_valid = br("single_instr_valid");
00225 F instr_valid2 = br("single_instr_valid2");
00226
00227 F LD = sc("LD");
00228
00229 F regfile = sr("mem@singleRF");
00230 F init_regfile = si("initRF");
00231 F instr_buffer_valid = br("single_instr_buffer_valid");
00232 F instr_buffer = sr("single_instr_buffer");
00233 F init_instr_buffer_valid = FALSE();
00234 F init_instr_buffer = si("init_instr_buffer");
00235
00236 F instr_buffer_load = instr_valid & !instr_buffer_valid;
00237 F next_instr_buffer = mux(instr_buffer_load,
00238 instr_data_reg1,
00239 instr_buffer);
00240
00241 instr_buffer << (init_instr_buffer % next_instr_buffer);
00242 F instr_pointer = br("instr_pointer");
00243 F first_instr = uif("first_instr",
00244 instr_buffer);
00245
00246 F second_instr = uif("second_instr",
00247 instr_buffer);
00248
00249 F executable_instr = mux(instr_pointer,
00250 second_instr,
00251 first_instr);
00252
00253
00254
00255 F executable_address1 = uif("src1",
00256 executable_instr);
00257 F executable_address2 = uif("src2",
00258 executable_instr);
00259 F executable_arg1 = uif2("mem@read",
00260 regfile,
00261 executable_address1);
00262 F executable_arg2 = uif2("mem@read",
00263 regfile,
00264 executable_address2);
00265 F executable_op = uif("op",
00266 executable_instr);
00267 F executable_alu_result = uif3("alu",
00268 executable_op,
00269 executable_arg1,
00270 executable_arg2);
00271 F executable_dest = uif("dest",
00272 executable_instr);
00273 F executable_load_value = uif("imm",
00274 executable_instr);
00275 F executable_select_alu = !(executable_instr == LD);
00276 F executable_result = mux(executable_select_alu,
00277 executable_alu_result,
00278 executable_load_value);
00279
00280 F executable_instr_write = instr_buffer_valid;
00281
00282 F next_regfile = mux(executable_instr_write,
00283 uif3("mem#write",
00284 regfile,
00285 executable_dest,
00286 executable_result),
00287 regfile);
00288 regfile << (init_regfile % next_regfile);
00289
00290 F instr_ready = (!instr_buffer_valid);
00291
00292 F next_instr_valid = (instr_ready & instr_valid2) | ((!instr_ready) & instr_valid);
00293 F next_instr_valid2 = (instr_ready & FALSE()) | ((!instr_ready) & instr_valid2);
00294 instr_valid << (TRUE() % next_instr_valid);
00295 instr_valid2 << (FALSE() % next_instr_valid2);
00296
00297 F next_instr_data_reg1 = mux(instr_ready,
00298 instr_data_reg2,
00299 instr_data_reg1);
00300
00301 F next_instr_data_reg2 = mux(instr_ready,
00302 instr_data,
00303 instr_data_reg2);
00304
00305 instr_data_reg1 << (instr_data1 % next_instr_data_reg1);
00306 instr_data_reg2 << (instr_data2 % next_instr_data_reg2);
00307
00308 F next_instr_pointer = (executable_instr_write & (!instr_pointer)) | ((!executable_instr_write) & instr_pointer);
00309
00310 instr_pointer << (FALSE() % next_instr_pointer);
00311
00312 F instr_committed = br("single_instr_committed");
00313 F next_instr_committed = (instr_pointer & executable_instr_write) | instr_committed;
00314 instr_committed << (FALSE() % next_instr_committed);
00315
00316
00317 F next_instr_buffer_valid = ((instr_ready & instr_valid) | instr_buffer_valid) & (!next_instr_committed);
00318 instr_buffer_valid << (init_instr_buffer_valid % next_instr_buffer_valid);
00319
00320 F arbitrary_read_address = si("read_address");
00321 F regfile_read_data = uif2("mem@read",
00322 regfile,
00323 arbitrary_read_address);
00324
00325 array_insert_last(Fnode*, result_array, instr_ready.raw);
00326 array_insert_last(Fnode*, result_array, instr_committed.raw);
00327 array_insert_last(Fnode*, result_array, regfile_read_data.raw);
00328 return result_array;
00329 }
00330
00331
00332
00333 }