есть что-то типа примитивного софт-процессора - CmdAddr - номер выполняемого оператора, Cmd - код оператора, и с десяток различных инструкций.
Если оставить все инструкции и собрать проект, то клок можно выставить только в 50МГц (есть долгие инструкции, в качестве примера, я написал инструкцию деления). Если закомментировать несколько "долгих инструкций", то проект можно собрать с клоком в 200МГц.
Реально я понимаю, что, если я для самого себя условлюсь, что после некоторых инструкций я поставлю 1-2-3 такта пустые инструкции, а длительность выполнения этих инструкций будет не один клок, а 2-3-4, то все будет работать, но вот как это объяснить квартусу?
Заводить кучу клоков, синхронизировать данные между ними - получается очень заумно и неудобно.
Может есть какой-то простой способ как сказать, что де
инструкция Номер 1 и 2 может работать два такта,
инструкция Номер 3 может работать 3 такта,
инструкия Номер 4 - может работать 4 такта
и пусть квартус не парится и не доводит тайминг этих долгих инструкций до высокой частоты?
Научите, пожалуйста, меня, кто знает, как это сделать!
Спасибо
ИИВ
Код
reg Clk; // клок
reg [31:0] In1Reg;
reg [31:0] In2Reg;
reg [31:0] OutReg;
reg [8:0] CmdAddr;
reg [17:0] CmdA[0:511]; // список команд-операций как-то где-то инициализируемый
reg [17:0] Cmd;
always @(posedge Clk)
begin
Cmd<=CmdA[CmdAddr+1];
if(Cmd[17]) CmdAddr<=Cmd[8:0];
else
begin
CmdAddr<=CmdAddr+1;
case(Cmd[16:14])
3'b000: OutReg<=In1Reg+In2Reg; // было бы классно выполнять ее 2 такта
3'b001: OutReg<=In1Reg-In2Reg; // было бы классно выполнять ее 2 такта
3'b010: OutReg<=In1Reg*In2Reg; // было бы классно выполнять ее 3 такта
3'b011: OutReg<=In1Reg/In2Reg; // было бы классно выполнять ее 4 такта
3'b100: OutReg<=In1Reg&In2Reg; // должна выполниться за такт
3'b101: OutReg<=In1Reg^In2Reg; // должна выполниться за такт
3'b110: OutReg<=In1Reg|In2Reg; // должна выполниться за такт
3'b111: // пустой оператор
endcase
end
end
reg [31:0] In1Reg;
reg [31:0] In2Reg;
reg [31:0] OutReg;
reg [8:0] CmdAddr;
reg [17:0] CmdA[0:511]; // список команд-операций как-то где-то инициализируемый
reg [17:0] Cmd;
always @(posedge Clk)
begin
Cmd<=CmdA[CmdAddr+1];
if(Cmd[17]) CmdAddr<=Cmd[8:0];
else
begin
CmdAddr<=CmdAddr+1;
case(Cmd[16:14])
3'b000: OutReg<=In1Reg+In2Reg; // было бы классно выполнять ее 2 такта
3'b001: OutReg<=In1Reg-In2Reg; // было бы классно выполнять ее 2 такта
3'b010: OutReg<=In1Reg*In2Reg; // было бы классно выполнять ее 3 такта
3'b011: OutReg<=In1Reg/In2Reg; // было бы классно выполнять ее 4 такта
3'b100: OutReg<=In1Reg&In2Reg; // должна выполниться за такт
3'b101: OutReg<=In1Reg^In2Reg; // должна выполниться за такт
3'b110: OutReg<=In1Reg|In2Reg; // должна выполниться за такт
3'b111: // пустой оператор
endcase
end
end