(--
    'DataMemory.balsa'
     The Data memory model for the SAMIPS architecture  with precise exceptions 
       
     June 2004, 
--)


import [type]

procedure DataMemory (input  DataAdd   : MemAdd;
	              input  WriteData : MemWord;
	              output MemData   : word)
is variable s : String
   variable mem : BalsaMemory
   variable f : DataAndLine
   variable data, MemWord: MemWord
   variable Add_R : word
   variable dt  : DataType
   variable  w : bit

begin
  mem := BalsaMemoryNew ();
  f.f := FileOpen ("Dataall.txt", read);
  f.lineNo := 0;
  loop while not FileEOF (f.f) then
      s := FileReadLine (f.f);
      s := "0x" + SubString(s, 10, 8);
      mem := BalsaMemoryWrite({9, 32}, mem, f.lineNo, FromString(word, s, s));         
      f.lineNo := (f.lineNo + 1 as DataSize)  
  end;
  loop
      select DataAdd, WriteData  then  Add_R := DataAdd.a   ||
                                       dt    := DataAdd.dt  ||
                                       w     := (DataAdd.rNw as bit) ||
                                       data  := WriteData
     end;     
     if #Add_R[28] then 
          Add_R := (Add_R - 268435456 as word)  -- 16#10000000
     else if #Add_R[22] then 
              Add_R := (Add_R - 4201216 as word)  -- 16#00401B00
          end
     end;  
   
     MemWord := (BalsaMemoryRead({9, 32}, mem, (#(Add_R)[10..2] as DataSize)) as MemWord);  

     if w then            
             case dt of 
               WL then case (#(Add_R)[1..0] as 2 bits) of
                         0 then data:= {data.w3, MemWord.w1, MemWord.w2, MemWord.w3}
                       | 1 then data:= {data.w2, data.w3,   MemWord.w2, MemWord.w3}
                       | 2 then data:= {data.w1, data.w2,   data.w3,   MemWord.w3}
		       end            
             | WR then case (#(Add_R)[1..0] as 2 bits) of
                         3 then data:= {MemWord.w0, MemWord.w1, MemWord.w2, data.w0}
                       | 2 then data:= {MemWord.w0, MemWord.w1, data.w0,   data.w1}
                       | 1 then data:= {MemWord.w0, data.w0,   data.w1,   data.w2}
		       end
             | H  then if #(Add_R)[1] then MemWord.w3 :=  data.w1||
                                           MemWord.w2 :=  data.w0 
                                      else MemWord.w1 :=  data.w1||
                                           MemWord.w0 :=  data.w0
                                      end;
                                      data := MemWord
             | B  then case (#(Add_R)[1..0] as 2 bits) of
                          0 then MemWord.w0 := data.w0
                       |  1 then MemWord.w1 := data.w0
                       |  2 then MemWord.w2 := data.w0
                            else MemWord.w3 := data.w0
                       end;
                       data := MemWord
             end;
             mem:= BalsaMemoryWrite({9, 32}, mem, (#(Add_R)[10..2] as DataSize), (data as word)) ||
             print "w: ",NumberToString (word, Add_R, 16, 0, 1), " D: ", NumberToString (word, (data as word), 16, 0, 1) 
      else 
             case dt of 
               W then data := MemWord
             | WL then case (#(Add_R)[1..0] as 2 bits) of
                         0 then data:= {data.w0, data.w1,   data.w2,   MemWord.w0}
                       | 1 then data:= {data.w0, data.w1,   MemWord.w0, MemWord.w1}
                       | 2 then data:= {data.w0, MemWord.w0, MemWord.w1, MemWord.w2}
                       else data := MemWord
		       end 
             | WR then case (#(Add_R)[1..0] as 2 bits) of
                         3 then data:= {MemWord.w3, data.w1,   data.w2,   data.w3}
                       | 2 then data:= {MemWord.w2, MemWord.w3, data.w2,   data.w3}
                       | 1 then data:= {MemWord.w1, MemWord.w2, MemWord.w3, data.w3}
                       else data := MemWord
		       end     
             | B, BU then case (#(Add_R)[1..0] as 2 bits) of
                             0 then data.w0 := MemWord.w0
                          |  1 then data.w0 := MemWord.w1
                          |  2 then data.w0 := MemWord.w2
                               else data.w0 := MemWord.w3
                          end;
                          if (dt = B) and (data.w0 > 127) then data := {data.w0, 255, 255, 255}
                                                          else data := {data.w0, 0, 0, 0}  end
             | H, HU then if #(Add_R)[1] then data.w1 := MemWord.w3 ||
                                              data.w0 := MemWord.w2 
                                         else data.w1 := MemWord.w1 ||
                                              data.w0 := MemWord.w0
                                         end; 
                          if (dt = H) and (data.w1 > 127) then data := {data.w0, data.w1, 255, 255}
                                                          else data := {data.w0, data.w1, 0, 0} end
             end;
             print "r: ",NumberToString (word, Add_R, 16, 0, 1), " D: ", NumberToString (word, (data as word), 16, 0, 1) ||
             MemData <- (data as word)
     end
  end
end       
