Main Page | Class List | File List | Class Members | File Members

micro_arch.c

Go to the documentation of this file.
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   // all the data for first instruction
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   // all the data for second instruction
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   // next state function of instr_buffer_valid
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   // print the double micro-arch
00180   //st_table *processedTable = st_init_table( (int (*)() ) st_ptrcmp, (int (*)() ) st_ptrhash );
00181   //Net_PrintFormula(double_net, array_fetch(Fnode *, double_net->formulas,0),  processedTable);
00182   //Net_PrintFormula(double_net, array_fetch(Fnode *, double_net->formulas,1),  processedTable);
00183   //Net_PrintFormula(double_net, array_fetch(Fnode *, double_net->formulas,2),  processedTable);
00184   // print the VHDL
00185   //Net_PrintVHDL(double_net, stdout, 4);
00186   //return double_regfile_data;
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   // print the single micro-arch
00196   //st_table *processedTable = st_init_table( (int (*)() ) st_ptrcmp, (int (*)() ) st_ptrhash );
00197   //Net_PrintFormula(single_net, array_fetch(Fnode *, single_net->formulas,0),  processedTable);
00198   //Net_PrintFormula(single_net, array_fetch(Fnode *, single_net->formulas,1),  processedTable);
00199   //Net_PrintFormula(single_net, array_fetch(Fnode *, single_net->formulas,2),  processedTable);
00200   //Net_PrintVHDL(single_net, stdout, 4);
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   //st_table *processedTable = st_init_table( (int (*)() ) st_ptrcmp, (int (*)() ) st_ptrhash );
00208   //Net_PrintFormula(fail_net, array_fetch(Fnode *, fail_net->formulas,0),  processedTable);
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   // all the data for executable instruction
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   // next state function of instr_buffer_valid
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 } // "C" linkage

Generated on Thu Oct 11 11:47:27 2007 for Tarski by  doxygen 1.3.9.1