Comment briser toujours bloquer en Verilog?

Je suis en train de simuler un simple processeur MIPS à l'aide de code de comportement en Verilog. J'ai fini d'écrire le code mais j'ai une dernière étape où j'ai envie de casser la bloque toujours après avoir fait avec de l'exécution de la MIPS instructions. Voici mon code:

module MIPS_Processor(output reg[7:0] LEDs, input[7:0] Switches);
reg [31:0] memory[0:4095];   //4K memory cells that are 8 bits wide
reg [31:0] code[0:1023];     //1K memory cells that are 8 bits wide
reg [31:0] registers[0:31];  //32 registers that are 32 bits wide
reg [31:0] PC;               //The program counter
reg [31:0] instruction;
reg [5 :0] op;
reg [4 :0] rs;
reg [4 :0] rt;
reg [4 :0] rd;
reg [4 :0] shamt;
reg [5 :0] funct;
reg signed [15:0] immediate_offset;
reg [25:0] target;
reg [1:0] instruction_type; //00 --> R | 01 --> I | 10 --> J | 11 --> EXTRA
reg [31:0] rs_value;
reg [31:0] rt_value;
reg [31:0] rd_value;
reg done = 0;
/*
Here we insert the code in the code array
*/
initial
begin
PC = 0;
end
always
begin
//1. Fetch an instruction from memory
instruction = code[PC];
//2. Increment the program counter register (by the instruction length)
PC = PC + 1;
//3. Decode the instruction
/*
The instructions are:
6   5    5    5    5    6
_____________________________
or    rd, rs, rt           | 0 | rs | rt | rd | 0 | 0x25 |
6    5    5        16
_____________________________
ori  rt, rs, immediate    | 0xd | rs | rt |  immediate  |
6   5    5    5    5    6
_____________________________
and  rd, rs, rt           | 0 | rs | rt | rd | 0 | 0x24 |
6    5    5        16
_____________________________
andi rt, rs, immediate    | 0xc | rs | rt |  immediate  |
6   5    5         16
_____________________________
beq  rs, rt, offset       | 4 | rs | rt |    offset     |
6   5    5    5    5    6
_____________________________
sub  rd, rs, rt           | 0 | rs | rt | rd | 0 | 0x22 |
6   5    5    5    5    6
_____________________________
add  rd, rs, rt           | 0 | rs | rt | rd | 0 | 0x20 |
6    5    5       16
_____________________________
addi rt, rs, immediate    | 8 | rs | rt |   immediate   |
6             26
_____________________________
j    target               | 2 |         target          |
6   5    5    5    5    6
_____________________________
slt  rd, rs, rt           | 0 | rs | rt | rd | 0 | 0x2a |
6     5    5        16
_____________________________
lw   rt, rs[offset]       | 0x23 | rs | rt |   offset   |
6     5    5        16
_____________________________
sw   rt, rs[offset]       | 0x2b | rs | rt |   offset   |
::EXTRA INSTRUCTIONS::
6    5            21
_____________________________
input  rs                 | 4 |  rs  |        0         |
6    5            21
_____________________________
output rs                 | 4 |  rs  |        1         |
*/
op[5:0] = instruction[31:26];
case(op)
0: /* R-type */
begin
rs = instruction[25:21];
rt = instruction[20:16];
rd = instruction[15:11];
shamt = instruction[10:6];
funct = instruction[5:0];
instruction_type = 2'b00;
end
1: /* END OF CODE */
begin
//$finish;
end
2: /* J-type */
begin
target = instruction[25:0];
instruction_type = 2'b10;
end
4: /* EXTRA */
begin
rs = instruction[25:21];
funct = instruction[20:0];
instruction_type = 2'b11;
end
default: /* I-type */
begin
rs = instruction[25:21];
rt = instruction[20:16];
immediate_offset = instruction[15:0];
instruction_type = 2'b01;
end
endcase
//4. Fetch operands, if any, usually from registers
case(instruction_type)
2'b00: /* R-type */
begin
rs_value = registers[rs];
rt_value = registers[rt];
end
2'b01: /* I-type */
begin
rs_value = registers[rs];
end
2'b11: /* EXTRA */
begin
if(funct == 1) rs_value = registers[rs];
end
endcase
//5. Perform the operation
case(instruction_type)
2'b00: /* R-type */
begin
case(funct)
2'h20: /* add  rd, rs, rt */
begin
rd_value = rs_value + rt_value;
end
2'h22: /* sub  rd, rs, rt */
begin
rd_value = rs_value - rt_value;
end
2'h24: /* and  rd, rs, rt */
begin
rd_value = rs_value & rt_value;
end
2'h25: /* or    rd, rs, rt */
begin
rd_value = rs_value | rt_value;
end
2'h2a: /* slt  rd, rs, rt */
begin
rd_value = rs_value < rt_value? 1 : 0;
end
endcase
end
2'b01: /* I-type */
begin
case(op)
4: /* beq  rs, rt, offset */
begin
if(rs_value < rt_value) PC = immediate_offset;
end
8: /* addi rt, rs, immediate */
begin
rt_value = rs_value + immediate_offset;
end
1'hc: /* andi rt, rs, immediate */
begin
rt_value = rs_value & immediate_offset;
end
1'hd: /* ori  rt, rs, immediate */
begin
rt_value = rs_value | immediate_offset;
end
2'h23: /* lw   rt, rs[offset] */
begin
rt_value = memory[rs + immediate_offset];
end
2'h2b: /* sw   rt, rs[offset] */
begin
memory[rs + immediate_offset] = rt_value;
end
endcase
end
2'b10: /* J-type */
begin
case(op)
2: /* j    target */
begin
PC = target;
end
endcase
end
2'b11: /* EXTRA */
begin
case(funct)
0: /* input  rs */
begin
rs_value[7:0] = Switches;
end
1: /* output rs */
begin
LEDs = rs_value[7:0];
end
endcase
if(funct == 1) rs_value = registers[rs];
end
endcase
//6. Store the results
case(instruction_type)
2'b00: /* R-type */
begin
registers[rd] = rd_value;
end
2'b01: /* I-type */
begin
case(op)
8: /* addi rt, rs, immediate */
begin
registers[rt] = rt_value;
end
1'hc: /* andi rt, rs, immediate */
begin
registers[rt] = rt_value;
end
1'hd: /* ori  rt, rs, immediate */
begin
registers[rt] = rt_value;
end
2'h23: /* lw   rt, rs[offset] */
begin
registers[rt] = rt_value;
end
endcase
end
2'b11: /* EXTRA */
begin
if(funct == 0) registers[rs] = rs_value;
end
endcase
end
endmodule

J'ai essayé $finir, mais ça ne fonctionne pas:

1: /* END OF CODE */
begin
//$finish;
end

Alors, comment puis-je rompre le always bloc? ou dois-je utiliser autre chose à la place?

OriginalL'auteur Eng.Fouad | 2012-03-27