Skip to content

Instantly share code, notes, and snippets.

@simonesestito
Last active January 11, 2023 16:10
Show Gist options
  • Save simonesestito/8c61c627fdd502f871987ce685213120 to your computer and use it in GitHub Desktop.
Save simonesestito/8c61c627fdd502f871987ce685213120 to your computer and use it in GitHub Desktop.
FIFO Modelica explanation: more available at https://www.overleaf.com/read/xtjqpcnzshmj
block Client
parameter Real T = 1; // O meno!
// Variabili lato lettura (server -> client)
OutputBoolean readsignal;
InputInteger readfifodata[1];
InputBoolean datavailable;
// Variabili lato scrittura (client -> server)
OutputInteger writefifodata[2]; // M = 2
OutputBoolean writesignal;
InputBoolean spaceavailable;
// Stato e variabili
Integer result;
Integer state;
algorithm
when initial() then
// server -> client
readsignal := false;
// client -> server
writesignal := false;
writefifodata[1] := 0;
writefifodata[2] := 0;
// Stato
result := 0;
state := 0;
elsewhen sample(0, T) then
if pre(state) == 0 then
writefifodata[1] := myrandint();
writefifodata[2] := myrandint();
state := 1;
elseif pre(state) == 1 and pre(spaceavailable) then
writesignal := not(pre(writesignal));
state := 2;
elseif pre(state) == 2 and pre(datavailable) then
readsignal := not(pre(writesignal));
state := 3;
elseif pre(state) == 3 then
result := pre(readfifodata[1]);
state := 0; // Ricomincia
end if;
end when;
end Client;
block FIFO
parameter Integer M = 1; // size IO array
parameter Integer N = 100; // fifo size
// read side
InputBoolean readsignal;
OutputInteger readfifodata[M]; // outputdata
OutputBoolean datavailable;
// write side
InputBoolean writesignal;
InputInteger writefifodata[M]; // inputdata
OutputBoolean spaceavailable;
Integer fifo[N, M]; // fifo of input msg
Integer oldest;
Integer newest;
Integer fifosize;
Boolean readsigint;
Boolean writesigint;
equation
readsigint = not(pre(readsignal) == readsignal) ;
writesigint = not(pre(writesignal) == writesignal) ;
algorithm
when initial() then
datavailable := false;
spaceavailable := true;
fifosize := 0;
oldest := 1; // where to read
newest := 1; // where to write
for j in 1:M loop
readfifodata[j] := 0;
end for;
for i in 1:N loop
for j in 1:M loop
fifo[i,j] := 0;
end for; // j
end for; // i
elsewhen (readsigint and writesigint ) then
//assert(false, "channel: Simultaneous read and write", AssertionLevel.warning);
if (pre(fifosize) < N)
then
// write
for j in 1:M loop
fifo[pre(newest), j] := writefifodata[j];
end for;
newest := mod(pre(newest), N) + 1; // mod(pre(newest) + 1 - 1, N) + 1
// read
for j in 1:M loop
readfifodata[j] := fifo[pre(oldest), j] ;
end for;
oldest := mod(pre(oldest), N) + 1 ;
else // pre(fifosize) >= N
// read
for j in 1:M loop
readfifodata[j] := fifo[pre(oldest), j] ;
end for;
oldest := mod(pre(oldest), N) + 1;
// write
for j in 1:M loop
fifo[pre(newest), j] := writefifodata[j];
end for;
newest := mod(pre(newest), N) + 1; // mod(pre(newest) + 1 - 1, N) + 1
end if;
elsewhen (readsigint and not(writesigint) and (pre(fifosize) >= 1) ) then
// there is something to read
//assert(false, "channel: Just read", AssertionLevel.warning);
for j in 1:M loop
readfifodata[j] := fifo[pre(oldest), j] ;
end for;
fifosize := pre(fifosize) - 1;
spaceavailable := true;
datavailable := if (fifosize >= 1) then true else false;
oldest := mod(pre(oldest), N) + 1;
elsewhen (not(readsigint) and writesigint and (pre(fifosize) < N) ) then
//assert(false, "channel: Just write", AssertionLevel.warning);
// there is space for writing
for j in 1:M loop
fifo[pre(newest), j] := writefifodata[j];
end for;
newest := mod(pre(newest), N) + 1;
fifosize := pre(fifosize) + 1;
datavailable := true;
spaceavailable := if (fifosize < N) then true else false;
for j in 1:M loop
readfifodata[j] := fifo[pre(oldest), j] ;
end for;
end when;
end FIFO;
block Receiver
parameter Real T = 1.0;
InputBoolean datavailable; // Controlla se il dato è disponibile da leggere
InputInteger readfifodata[1]; // Eventuale dato da leggere, inserito dalla FIFO
OutputBoolean readsignal; // Scatena l'evento di avvenuta lettura, come writesignal per sender.mo
Integer x; // Dato letto
Integer state; // Stato di lettura / attesa lettura / etc...
algorithm
when initial() then
x := 0;
state := 0;
readsignal := false;
elsewhen sample(0,T) then
if (pre(state) == 0) and pre(datavailable) then // ask for data
readsignal := not(pre(readsignal));
state := 1;
elseif (state == 1) then
x := pre(readfifodata[1]);
// TODO: Fai qualcosa con X
state := 0;
end if;
end when;
end Receiver;
block Sender
parameter Real T = 1.0;
InputBoolean spaceavailable;
OutputInteger writefifodata[1];
OutputBoolean writesignal;
Integer state;
algorithm
when initial() then
writesignal := false;
state := 0;
elsewhen sample(0,T) then
if (pre(state) == 0) then
writefifodata[1] := myrandomint(10); // TODO
state := 10;
elseif (pre(state) == 10) and pre(spaceavailable) then
writesignal := not(pre(writesignal));
state := 0;
end if;
end when;
end Sender;
block Server
parameter Real T = 1; // O meno, soprattutto con più client!
// Variabili lato lettura (client -> server)
OutputBoolean readsignal;
InputInteger readfifodata[2]; // M = 2
InputBoolean datavailable;
// Variabili lato scrittura (server -> client)
OutputInteger writefifodata[1];
OutputBoolean writesignal;
InputBoolean spaceavailable;
// Stato corrente e variabili
Integer state;
Integer operands[2];
algorithm
when initial() then
// client -> server
readsignal := false;
// server -> client
writesignal := false;
writefifodata[1] := 0;
// Stato
state := 0;
operands[1] := 0;
operands[2] := 0;
elsewhen sample(0, T) then
if pre(state) == 0 and pre(datavailable) then
readsignal := not(pre(readsignal));
state := 1;
elseif pre(state) == 1 then
// TODO: Receive input data
operands[1] := readfifodata[1];
operands[2] := readfifodata[2];
state := 2;
elseif pre(state) == 2 then
// TODO: Calculate response
writefifodata[1] := operands[1] - operands[2];
state := 3;
elseif pre(state) == 3 and pre(spaceavailable) then
writesignal := not(pre(writesignal));
state := 0; // Ricomincia
end if;
end when;
end Server;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment