Простой компьютерный дизайн Мориса Мано с использованием Verilog
Я должен спроектировать простой 16-битный компьютер Moris Mano, в состав которого входят Alu, блок управления, регистры и шина.
Вопрос в том, что я немного запутался в типе переменных. Например, я должен использовать провод для D0,D1 ... D7 и T0,T1, .., T7, или я должен использовать рег.? И если я должен использовать провод, как назначить им значение в блоке Always @(posedge clock)?
Часть моего кода выглядит следующим образом:
module Control_Unit_Core(PC_inc,DR_inc,AC_inc,AC_clr,IR_load,DR_load,AR_load,PC_load,AC_load,RAM_load,RAM_read,ALU_select,ALU_enable, IR,DR,AC,clock);
output PC_inc,DR_inc,AC_inc,AC_clr,IR_load,DR_load,AR_load,PC_load,AC_load,RAM_load,RAM_read,ALU_enable;
output [1:0] ALU_select;
input [9:0] IR,DR,AC;
input clock;
reg [2:0] palseCounter=3'b111;
wire [7:0] T=8'b00000000;
wire [7:0] D=8'b00000000;
wire [5:0] B=6'b000000;
wire [9:0] ADDRESS=10'b0000000000;
reg HLT=0,SC_reset=0,I=0,Z=0,R=0;
wire Ram_load=0,DR_load=0,AR_load=0,AC_load=0,IR_load=0,PC_load=0;
wire PC_inc=0,DR_inc=0,AC_inc=0;
wire AC_clr=0;
reg Ram_read=0;
reg Alu_enable=0;
reg [2:0] Bus_select=3'b000;
reg [1:0] Alu_select=3'b00;
always @(posedge clock)
begin
pulseCounter <= pulseCounter+1'
T_Generator(T,HLT,SC_reset,pulseCounter);
D_B_Generator(D,B,ADDRESS,I,IR);
Registers_Load_Generator(Ram_load,DR_load,AR_load,AC_load,IR_load,PC_load,D,T,I);
Z<=AC[9];
R<=(~I)&D[7]&T[3];
HLT<=R&B[0];
Registers_Inc_Clr_Generator(PC_inc,DR_inc,AC_inc,AC_clr,D,T,B,AC,DR,R,Z);
Bus_Select_Generator(Bus_select,Ram_read,T,D,I);
Alu_Signal_Generator(Alu_select,Alu_enable,T,D);
SC_reset <=(D[0]&T[6])|(D[1]&T[6])|(D[2]&T[6])|(D[3]&T[5])|(D[4]&T[5])|((~I)&D[7]&T[4])|T[7];
end
endmodule
Кроме того, написанный код для задач T_Generator и D_Generator выглядит следующим образом.
task T_Generator(output [7:0]T,input hlt, SC_reset,inout [2:0]palseCounter);
if(~hlt)
begin
if(SC_reset)
palseCounter=3'b000;
case(palseCounter)
3'b000 : T=8'b00000001;
3'b001 : T=8'b00000010;
3'b010 : T=8'b00000100;
3'b011 : T=8'b00001000;
3'b100 : T=8'b00010000;
3'b101 : T=8'b00100000;
3'b110 : T=8'b01000000;
3'b111 : T=8'b10000000;
endcase
end
else
begin
T=8'b00000000;
palseCounter=3'b111;
end
endtask
///------------------------------------
task D_B_Generator(output [7:0] D,output [5:0] B,output [9:0] ADDRESS ,output I,input [9:0] IR);
I=IR[9];
case(IR[8:6])
3'b000 : D=8'b00000001;
3'b001 : D=8'b00000010;
3'b010 : D=8'b00000100;
3'b011 : D=8'b00001000;
3'b100 : D=8'b00010000;
3'b101 : D=8'b00100000;
3'b110 : D=8'b01000000;
3'b111 : D=8'b10000000;
endcase
B=IR[5:0];
ADDRESS=IR[5:0];
endtask
Заранее спасибо.
1 ответ
Короткий ответ:
Они должны быть рег. И, пожалуйста, сбросьте ваши переменные, не используйте объявление времени инициализации, если вы планируете синтезировать это.
Средний ответ:
Если вы назначаете в блоке всегда, используйте reg, иначе используйте wire. Пожалуйста, никогда не используйте объявление времени инициализации на проводах. При правильном использовании проводов у вас будет конфликт дисков, который может вас запутать интересными способами.
Более длинный ответ:
В любой момент их значение известно, не глядя на предыдущее значение? Провода используются для таких вещей, как операторы присваивания и связности, потому что (с точки зрения симулятора) в проводе нет понятия памяти. Один просто смотрит на RHS назначения и знает, что будет LHS. Конечно, есть разрешение силы привода, но это более сложный вопрос. Есть также # задержки, но давайте пока не будем о них беспокоиться - если вам нужно поместить их в RTL, вы, вероятно, делаете это неправильно.
Рег, однако, может быть назначена в любой точке и также имеет неблокирующие назначения (изменение значения откладывается до конца оценки временного интервала). Вы можете даже не обновлять reg каждый тактовый цикл, не говоря уже о каждом временном интервале (или даже многократно в каждом временном интервале).
Но давайте не будем вдаваться в подробности того, как можно написать симулятор сверх того, что содержалось в оригинальной спецификации Verilog 95.