📄 memctrl.v
字号:
input [7:0] sfrdatai;
output [7:0] sfrdatamcu;
wire [7:0] sfrdatamcu;
input [6:0] sfraddr;
input sfrwe;
//---------------------------------------------------------------
// Registers
//---------------------------------------------------------------
// Program Counter register
reg [15:0] pc;
reg [15:0] pc_inc;
reg [15:0] pc_add;
reg [15:0] pc_rel;
// Data Pointer registers
reg [15:0] dptr;
reg [15:0] dp_inc;
reg [15:0] dp_add;
// Data Pointer 1 registers
reg [15:0] dptr1;
reg [15:0] dp1_inc;
reg [15:0] dp1_add;
// Data Pointer select register
reg [7:0] dps;
// Address Buffer register
reg [15:0] addrbuff;
// Realtive address register
reg [7:0] rel;
//---------------------------------------------------------------
// Control signals
//---------------------------------------------------------------
// Program Counter control signals
reg pcince; // PC increment enable
wire pcrele; // PC + REL count enable
// Data Pointer control signals
wire dpince; // DPTR increment enable
wire dpadde; // DPTR + A count enable
wire dplwe; // DPTR low byte write enable
wire dphwe; // DPTR high byte write enable
// Address Buffer control signals
wire membufflwe; // Memory to Buffer low write en.
wire membuffhwe; // Memory to Buffer high write en.
wire rambufflwe; // RAM to Buffer low write en.
wire rambuffhwe; // RAM to Buffer high write en.
wire instrbuffwe; // Instr. to Buffer high write en.
// Memory Address control signals
wire pcaddsel; // PC + A count enable
wire dpaddsel; // DPTR + A count enable
wire dpsel; // DPTR select
wire risel; // Ri select
wire buffsel; // Buffer select
// Relative Address control signals
wire relwe; // Rel register write enable
// Opcode fetch enable for MOVC instructions
reg storefetche;
reg [3:0] stretchcount;
wire movxwait;
wire movxend;
reg movxendff;
reg mempsrd_int;
reg memrd_int;
wire mem_ack_psack_in;
wire mempsacko;
wire memack_int;
//------------------------------------------------------------------
// Program counter low byte output
//------------------------------------------------------------------
assign pclreg = pc[7:0] ;
//------------------------------------------------------------------
// Program counter low byte output
//------------------------------------------------------------------
assign pchreg = pc[15:8] ;
//------------------------------------------------------------------
// PC increment enable
// PC=PC+1
//------------------------------------------------------------------
always @(codefetche or
datafetche or
debugfetche or
intreq or
intcall or
a5instr or
debugreq or
debugprog or
mempsackint)
begin : pcince_hand
//------------------------------------------------------------------
if (
mempsackint &
(
(codefetche & ~intreq)
|
(
datafetche & ~intcall &
(
(~a5instr & ~debugreq)
|
~debugprog
)
)
|
(debugfetche & ~debugprog) // debugger mode, user program
)
)
begin
pcince = 1'b1 ;
end
else
begin
pcince = 1'b0 ;
end
end
//------------------------------------------------------------------
// PC + REL count enable
// PC=PC+REL
// MEMADDR=PC+REL
//------------------------------------------------------------------
assign pcrele =
((instr == SJMP & cycle == 2) |
(instr == JZ & cycle == 2 & accreg == 8'b00000000) |
(instr == JNZ & cycle == 2 & ~(accreg == 8'b00000000)) |
(instr == JC & cycle == 2 & cyflag) |
(instr == JNC & cycle == 2 & !cyflag) |
(instr == JB_BIT & cycle == 3 & bitvalue) |
(instr == JNB_BIT & cycle == 3 & !bitvalue) |
(instr == JBC_BIT & cycle == 3 & bitvalue) |
(instr == CJNE_A_ADDR & cycle == 3 & cdjump) |
(instr == CJNE_A_N & cycle == 3 & cdjump) |
(instr == CJNE_R0_N & cycle == 3 & cdjump) |
(instr == CJNE_R1_N & cycle == 3 & cdjump) |
(instr == CJNE_R2_N & cycle == 3 & cdjump) |
(instr == CJNE_R3_N & cycle == 3 & cdjump) |
(instr == CJNE_R4_N & cycle == 3 & cdjump) |
(instr == CJNE_R5_N & cycle == 3 & cdjump) |
(instr == CJNE_R6_N & cycle == 3 & cdjump) |
(instr == CJNE_R7_N & cycle == 3 & cdjump) |
(instr == CJNE_IR0_N & cycle == 3 & cdjump) |
(instr == CJNE_IR1_N & cycle == 3 & cdjump) |
(instr == DJNZ_R0 & cycle == 2 & cdjump) |
(instr == DJNZ_R1 & cycle == 2 & cdjump) |
(instr == DJNZ_R2 & cycle == 2 & cdjump) |
(instr == DJNZ_R3 & cycle == 2 & cdjump) |
(instr == DJNZ_R4 & cycle == 2 & cdjump) |
(instr == DJNZ_R5 & cycle == 2 & cdjump) |
(instr == DJNZ_R6 & cycle == 2 & cdjump) |
(instr == DJNZ_R7 & cycle == 2 & cdjump) |
(instr == DJNZ_ADDR & cycle == 3 & cdjump)) ? 1'b1
: 1'b0 ;
//------------------------------------------------------------------
// flush_ff
//------------------------------------------------------------------
always @(posedge clk)
begin
if (rst)
//-----------------------------------
// Synchronous reset
//-----------------------------------
begin
flush_ff <= 1'b0 ;
end
else
//-----------------------------------
// Synchronous write
//-----------------------------------
begin
if (pcrele | dpadde | buffsel)
begin
flush_ff <= 1'b1 ;
end
else if (mempsackint)
begin
flush_ff <= 1'b0 ;
end
end
end
//------------------------------------------------------------------
// flush output
//------------------------------------------------------------------
assign flush = (mempsackint & flush_ff)
? 1'b1 : 1'b0 ;
//------------------------------------------------------------------
// DPTR increment enable
// DPTR=DPTR+1
//------------------------------------------------------------------
assign dpince = (mempsackint & instr == INC_DPTR & cycle == 1)
? 1'b1 : 1'b0 ;
//------------------------------------------------------------------
// DPTR + A count enable
// PC=DPTR+A
//------------------------------------------------------------------
assign dpadde = (instr == JMP_A_DPTR & cycle == 1)
? 1'b1 : 1'b0 ;
//------------------------------------------------------------------
// DPTR low byte write enable
//------------------------------------------------------------------
assign dplwe = (mempsackint & instr == MOV_DPTR_N & cycle == 2)
? 1'b1 : 1'b0 ;
//------------------------------------------------------------------
// DPTR high byte write enable
//------------------------------------------------------------------
assign dphwe = (mempsackint & instr == MOV_DPTR_N & cycle == 1)
? 1'b1 : 1'b0 ;
//------------------------------------------------------------------
// Memory to Buffer low write enable
//------------------------------------------------------------------
assign membufflwe =
((instr == ACALL_0 & cycle == 1) |
(instr == ACALL_1 & cycle == 1) |
(instr == ACALL_2 & cycle == 1) |
(instr == ACALL_3 & cycle == 1) |
(instr == ACALL_4 & cycle == 1) |
(instr == ACALL_5 & cycle == 1) |
(instr == ACALL_6 & cycle == 1) |
(instr == ACALL_7 & cycle == 1) |
(instr == LCALL & cycle == 2) |
(instr == AJMP_0 & cycle == 1) |
(instr == AJMP_1 & cycle == 1) |
(instr == AJMP_2 & cycle == 1) |
(instr == AJMP_3 & cycle == 1) |
(instr == AJMP_4 & cycle == 1) |
(instr == AJMP_5 & cycle == 1) |
(instr == AJMP_6 & cycle == 1) |
(instr == AJMP_7 & cycle == 1) |
(instr == LJMP & cycle == 2)) ? 1'b1
: 1'b0 ;
//------------------------------------------------------------------
// Memory to Buffer high write enable
//------------------------------------------------------------------
assign membuffhwe =
((instr == LCALL & cycle == 1) |
(instr == LJMP & cycle == 1)) ? 1'b1
: 1'b0 ;
//------------------------------------------------------------------
// RAM to Buffer low write enable
//------------------------------------------------------------------
assign rambufflwe =
((instr == RET & cycle == 2) |
(instr == RETI & cycle == 2)) ? 1'b1
: 1'b0 ;
//------------------------------------------------------------------
// RAM to Buffer high write enable
//------------------------------------------------------------------
assign rambuffhwe =
((instr == RET & cycle == 1) |
(instr == RETI & cycle == 1)) ? 1'b1
: 1'b0 ;
//------------------------------------------------------------------
// Instruction opcode to Buffer high write enable
//------------------------------------------------------------------
assign instrbuffwe =
((instr == ACALL_0 & cycle == 1) |
(instr == ACALL_1 & cycle == 1) |
(instr == ACALL_2 & cycle == 1) |
(instr == ACALL_3 & cycle == 1) |
(instr == ACALL_4 & cycle == 1) |
(instr == ACALL_5 & cycle == 1) |
(instr == ACALL_6 & cycle == 1) |
(instr == ACALL_7 & cycle == 1) |
(instr == AJMP_0 & cycle == 1) |
(instr == AJMP_1 & cycle == 1) |
(instr == AJMP_2 & cycle == 1) |
(instr == AJMP_3 & cycle == 1) |
(instr == AJMP_4 & cycle == 1) |
(instr == AJMP_5 & cycle == 1) |
(instr == AJMP_6 & cycle == 1) |
(instr == AJMP_7 & cycle == 1)) ? 1'b1
: 1'b0 ;
//------------------------------------------------------------------
// PC + A count enable
//------------------------------------------------------------------
assign pcaddsel =
(instr == MOVC_A_PC &
(
cycle == 1 |
(cycle == 2 & !mempsackint)
)
) ? 1'b1
: 1'b0 ;
//------------------------------------------------------------------
// DPTR + A count enable
// MEMADDR=DPTR+A
//------------------------------------------------------------------
assign dpaddsel =
(
(instr == JMP_A_DPTR & cycle == 1) |
(
instr == MOVC_A_DPTR &
(
cycle == 1 |
(cycle == 2 & !mempsackint)
)
)
) ? 1'b1 : 1'b0 ;
//------------------------------------------------------------------
// DPTR select
// MEMADDR=DPTR
//------------------------------------------------------------------
assign dpsel =
((instr == MOVX_A_IDPTR) &
((cycle == 1) |
(stretchcount == 4'b0010 |
stretchcount == 4'b0011 |
stretchcount == 4'b0100 |
stretchcount == 4'b0101 |
stretchcount == 4'b0110 |
stretchcount == 4'b0111 |
stretchcount == 4'b1000 |
(stretchcount == 4'b0001 & !mem_ack_psack_in)
)
)
) ? 1'b1 :
((instr == MOVX_IDPTR_A) &
((cycle == 1 | cycle == 2 |
(!mem_ack_psack_in & !movxendff)
) | // (cycle == 1 | cycle == 2 | !memack)
((stretchcount != 4'b0000) & (cycle == 3))
)
) ? 1'b1 : 1'b0 ;
//------------------------------------------------------------------
// Ri select
// MEMADDR low = Ri
//------------------------------------------------------------------
assign risel =
((instr == MOVX_A_IR0 | instr == MOVX_A_IR1) &
((cycle == 1) |
((stretchcount == 4'b0010 |
stretchcount == 4'b0011 |
stretchcount == 4'b0100 |
stretchcount == 4'b0101 |
stretchcount == 4'b0110 |
stretchcount == 4'b0111 |
stretchcount == 4'b1000 |
(stretchcount == 4'b0001 & !mem_ack_psack_in)
)
)
)
) ? 1'b1
:
((instr == MOVX_IR0_A | instr == MOVX_IR1_A) &
(!codefetche & !datafetche & !debugfetche) & !movxendff &
((cycle == 1 | cycle == 2 | !mem_ack_psack_in) |
((stretchcount != 4'b0000) & (cycle == 3))
)
) ? 1'b1
: 1'b0 ;
//------------------------------------------------------------------
// Buffer to PC write enable
// Buffer to Memory Address write enable
//------------------------------------------------------------------
assign buffsel =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -