📄 mem.v
字号:
else
STATE <= NEXT_STATE;
end
// make IF_KEEP
always @(ADR or IF_WIDTH) begin
IF_KEEP <= (~ADR[1]) & (~ADR[0]) & IF_WIDTH;
end
// make IF_FORCE
always @(IF_JP or IF_AD) begin
//IF_FORCE <= IF_JP | ((~IF_AD[1]) & (~IF_AD[0]));
IF_FORCE <= IF_JP | (~IF_AD[1]);
end
// make NEXT_STATE : state machine combinational circuit
always @(STATE or IF_ISSUE or MA_ISSUE or IF_FORCE or IF_KEEP or ACK) begin
case (STATE)
`S_IDLE: // S0 idle
if ({IF_ISSUE, MA_ISSUE} == 2'b00) NEXT_STATE <= `S_IDLE;
else if ({IF_ISSUE, MA_ISSUE} == 2'b10) NEXT_STATE <= `S_IFEX;
else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX;
else NEXT_STATE <= `S_MAEX_IFPD;
`S_IFEX: // S1 external fetch
if (ACK == 1'b0) NEXT_STATE <= `S_IFEX;
else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b000) NEXT_STATE <= `S_IDLE;
else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b001) NEXT_STATE <= `S_IDLE_IFKP;
else if ({IF_ISSUE, MA_ISSUE, IF_FORCE, IF_KEEP} == 4'b1000) NEXT_STATE <= `S_IFEX;
else if ({IF_ISSUE, MA_ISSUE, IF_FORCE, IF_KEEP} == 4'b1010) NEXT_STATE <= `S_IFEX;
else if ({IF_ISSUE, MA_ISSUE, IF_FORCE, IF_KEEP} == 4'b1001) NEXT_STATE <= `S_IFIN;
else if ({IF_ISSUE, MA_ISSUE, IF_FORCE, IF_KEEP} == 4'b1011) NEXT_STATE <= `S_IFEX;
else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b010) NEXT_STATE <= `S_MAEX;
else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b011) NEXT_STATE <= `S_MAEX_IFKP;
else if ({IF_ISSUE, MA_ISSUE, IF_KEEP} == 3'b110) NEXT_STATE <= `S_MAEX_IFPD;
else NEXT_STATE <= `S_MAEX_IFIN;
`S_MAEX: // S2 external data access
if (ACK == 1'b0) NEXT_STATE <= `S_MAEX;
else if ({IF_ISSUE, MA_ISSUE} == 2'b00) NEXT_STATE <= `S_IDLE;
else if ({IF_ISSUE, MA_ISSUE} == 2'b10) NEXT_STATE <= `S_IFEX;
else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX;
else NEXT_STATE <= `S_MAEX_IFPD;
`S_MAEX_IFPD: // S3 external data access, pending fetch
if (ACK == 1'b0) NEXT_STATE <= `S_MAEX_IFPD;
else NEXT_STATE <= `S_IFEX;
`S_IDLE_IFKP: // S4 idle, keeping lower un-decodeed instruction
if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b101) NEXT_STATE <= `S_IFEX;
else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b100) NEXT_STATE <= `S_IFIN;
else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX_IFKP;
else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b111) NEXT_STATE <= `S_MAEX_IFPD;
else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b110) NEXT_STATE <= `S_MAEX_IFIN;
else NEXT_STATE <= `S_IDLE_IFKP;
`S_IFIN: // S5 internal fetch from just keeping one
if ({IF_ISSUE, MA_ISSUE} == 2'b00) NEXT_STATE <= `S_IDLE;
else if ({IF_ISSUE, MA_ISSUE} == 2'b10) NEXT_STATE <= `S_IFEX;
else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX;
else NEXT_STATE <= `S_MAEX_IFPD;
`S_MAEX_IFKP: // S6 extenal data access, keeping lower un- decoded instruction
if (ACK == 1'b0) NEXT_STATE <= `S_MAEX_IFKP;
else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b101) NEXT_STATE <= `S_IFEX;
else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b100) NEXT_STATE <= `S_IFIN;
else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX_IFKP;
else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b111) NEXT_STATE <= `S_MAEX_IFPD;
else if ({IF_ISSUE, MA_ISSUE, IF_FORCE} == 3'b110) NEXT_STATE <= `S_MAEX_IFIN;
else NEXT_STATE <= `S_IDLE_IFKP;
`S_MAEX_IFIN: // S7 external data access and do internal fetch from just keeping
if (ACK == 1'b0) NEXT_STATE <= `S_MAEX_IFIN;
else if ({IF_ISSUE, MA_ISSUE} == 2'b00) NEXT_STATE <= `S_IDLE;
else if ({IF_ISSUE, MA_ISSUE} == 2'b10) NEXT_STATE <= `S_IFEX;
else if ({IF_ISSUE, MA_ISSUE} == 2'b01) NEXT_STATE <= `S_MAEX;
else NEXT_STATE <= `S_MAEX_IFPD;
default: NEXT_STATE <= `S_IDLE;
endcase
end
//-------------------------------
// ADR : external addresss output
//-------------------------------
// selector
always @(NEXT_STATE or MA_AD or IF_AD) begin
if (NEXT_STATE[1] == 1'b1) //memory access
ADR_PREV <= MA_AD;
else // instruction fetch
ADR_PREV <= IF_AD;
end
// output
always @(posedge CLK) begin
if ((NXTBUS == 1'b1) && (MEMEND == 1'b1)) begin
ADR <= ADR_PREV;
end
end
//-------------------------------------
// ACCESS_SZ : current data access size
//-------------------------------------
always @(posedge CLK) begin
if ((NXTBUS == 1'b1) && (MEMEND == 1'b1)) begin
ACCESS_SZ <= MA_SZ; // have meaning only when data access
end
end
//----------------------------
// DATO : external data output
//----------------------------
// prepare
always @(MA_SZ or MA_DW) begin
case (MA_SZ)
2'b00: begin // byte
DATO_PREV[31:24] <= MA_DW[7:0];
DATO_PREV[23:16] <= MA_DW[7:0];
DATO_PREV[15: 8] <= MA_DW[7:0];
DATO_PREV[ 7: 0] <= MA_DW[7:0];
end
2'b01: begin // word
DATO_PREV[31:24] <= MA_DW[15:8];
DATO_PREV[23:16] <= MA_DW[ 7:0];
DATO_PREV[15: 8] <= MA_DW[15:8];
DATO_PREV[ 7: 0] <= MA_DW[ 7:0];
end
2'b10: begin // long
DATO_PREV[31:24] <= MA_DW[31:24];
DATO_PREV[23:16] <= MA_DW[23:16];
DATO_PREV[15: 8] <= MA_DW[15: 8];
DATO_PREV[ 7: 0] <= MA_DW[ 7: 0];
end
default: // 2'b11 don't care
begin
DATO_PREV[31:24] <= MA_DW[31:24]; // Thorn Aitch 2003/12/10
DATO_PREV[23:16] <= MA_DW[23:16]; // Thorn Aitch 2003/12/10
DATO_PREV[15: 8] <= MA_DW[15: 8]; // Thorn Aitch 2003/12/10
DATO_PREV[ 7: 0] <= MA_DW[15: 8]; // Thorn Aitch 2003/12/10
end
endcase
end
// output
always @(posedge CLK) begin
if ((NXTBUS == 1'b1) && (MEMEND == 1'b1) && (MA_WR == 1'b1))
DATO <= DATO_PREV;
end
//----------------------------
// IF_DR : fetched instruction
//----------------------------
// capture DATI
always @(posedge CLK) begin
if ((MEMEND == 1'b1) & ((STATE == `S_IFEX) | ((STATE[2] == 1'b1) && (STATE[0] == 1'b1))))
begin
IF_STATE <= STATE;
IF_ADR1 <= ADR[1];
IF_IF_BUF <= IF_BUF;
IF_DR_PREV <= DATI;
end
end
// output to IF_DR
always @(IF_STATE or IF_ADR1 or IF_DR_PREV or IF_IF_BUF) begin
if (IF_STATE == `S_IFEX)
begin
// IF from 0,4,8,C
if (IF_ADR1 == 1'b0)
begin
IF_DR <= IF_DR_PREV[31:16];
end
// IF from 2,6,A,E
else
IF_DR <= IF_DR_PREV[15:0];
end
else
// IF from IF_BUF
//if ((IF_STATE[2] == 1'b1) && (IF_STATE[0] == 1'b1)) // `S_IFIN or `S_MAEX_IFIN
// IF_DR <= IF_IF_BUF; // Thorn Aitch 2003/12/10
//else // Thorn Aitch 2003/12/10
// IF_DR <= 32'hxxxxxxxx; // Thorn Aitch 2003/12/10
IF_DR <= IF_IF_BUF; // Thorn Aitch 2003/12/10
end
// output
//always @(posedge CLK) begin
// if ((MEMEND == 1'b1) & ((STATE == `S_IFEX) | ((STATE[2] == 1'b1) && (STATE[0] == 1'b1))))
// begin
// IF_DR <= IF_DR_PREV;
// end
//end
//---------------------------------------------------------------
// IF_BUF : buffer to keep the lower 16bit of previous long fetch
//---------------------------------------------------------------
always @(posedge CLK) begin
if (MEMEND == 1'b1) begin
if (STATE == `S_IFEX)
// IF from long space external
if ((IF_WIDTH == 1'b1) && (ADR[1] == 1'b0))
IF_BUF <= DATI[15:0];
end
end
//------------------
// MA_DR : read data
//------------------
// capture DATI
always @(posedge CLK) begin
if (ACK == 1'b1) begin // it must be captured by ACK (not MEMEND)
if ((STATE[1] == 1'b1) && (WE == 1'b0)) begin
MA_ACCESS_SZ <= ACCESS_SZ;
MA_ADR <= ADR[1:0];
MA_DR_PREV <= DATI;
end
end
end
// output to MA_DR with Sign Extended
always @(MA_ACCESS_SZ or MA_DR_PREV or MA_ADR) begin
case (MA_ACCESS_SZ)
2'b00: begin //byte
if ({MA_ADR[1], MA_ADR[0]} == 2'b00)
begin
for (i = 8 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[31];
MA_DR[7:0] <= MA_DR_PREV[31:24];
end
else if ({MA_ADR[1], MA_ADR[0]} == 2'b01)
begin
for (i = 8 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[23];
MA_DR[7:0] <= MA_DR_PREV[23:16];
end
else if ({MA_ADR[1], MA_ADR[0]} == 2'b10)
begin
for (i = 8 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[15];
MA_DR[7:0] <= MA_DR_PREV[15:8];
end
else if ({MA_ADR[1], MA_ADR[0]} == 2'b11)
begin
for (i = 8 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[7];
MA_DR[7:0] <= MA_DR_PREV[7:0];
end
end
2'b01: begin //word
if (MA_ADR[1] == 1'b0)
begin
for (i = 16 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[31];
MA_DR[15:0] <= MA_DR_PREV[31:16];
end
else
begin
for (i = 16 ; i <= 31 ; i = i + 1) MA_DR[i] <= MA_DR_PREV[15];
MA_DR[15:0] <= MA_DR_PREV[15:0];
end
end
2'b10: begin //long
MA_DR[31:0] <= MA_DR_PREV[31:0];
end
default : begin
//MA_DR[31:0] <= 32'hxxxxxxxx; // Thorn Aitch 2003/12/10
MA_DR[31:0] <= MA_DR_PREV[31:0]; // Thorn Aitch 2003/12/10
end
endcase
end
// output
//always @(posedge CLK) begin
// if (ACK == 1'b1) begin // it must be captured by ACK (not MEMEND)
// if ((STATE[1] == 1'b1) && (WE == 1'b0)) begin
// MA_DR <= MA_DR_PREV;
// end
// end
//end
//------------------------------------------
// IF_BUS : fetch access done to extenal bus
//------------------------------------------
always @(posedge CLK) begin
if (MEMEND == 1'b1) begin
if (NEXT_STATE == `S_IFEX)
IF_BUS <= 1'b1;
else
IF_BUS <= 1'b0;
end
end
//----------------------------------------------
// IF_STALL : fetch and memory access contention
//----------------------------------------------
always @(NEXT_STATE) begin
if (NEXT_STATE == `S_MAEX_IFPD)
IF_STALL <= 1'b1;
else
IF_STALL <= 1'b0;
end
//-------------------------
// WE : WISHBONE write/read
//-------------------------
// WE
always @(posedge CLK) begin
if (MEMEND == 1'b1) begin
if (((NEXT_STATE[1] == 1'b1) && (MA_WR == 1'b0)) || (NEXT_STATE == `S_IFEX))
WE <= 1'b0; // read
else
WE <= 1'b1; // write
end
end
//--------------------------
// STB : WISHBONE bus strobe
//--------------------------
always @(posedge CLK) begin
if (MEMEND == 1'b1) begin
STB <= NXTBUS;
end
end
//------------------------------------
// CYC :WOSHBONE show cycle to be kept
//------------------------------------
// req STB CYC
// ---------------
// RD,CYC off off
// nop on on
// WR off on
// nop on on
// off off
// prepare
always @(NXTBUS or NEXT_KEEP_CYC) begin
if ((NXTBUS == 1'b1) || (NEXT_KEEP_CYC == 1'b1))
CYC_PREV <= 1'b1;
else
CYC_PREV <= 1'b0;
end
// remember for next cyc
always @(posedge CLK) begin
if (MEMEND == 1'b1) begin
NEXT_KEEP_CYC <= KEEP_CYC;
end
end
// output
always @(posedge CLK) begin
if (MEMEND == 1'b1) begin
CYC <= CYC_PREV;
end
end
//----------------------------------------
// SEL : WISHBONE show valid data position
//----------------------------------------
// prepare
always @(NEXT_STATE or MA_SZ or MA_AD or IF_AD) begin
//if ((NEXT_STATE == `S_IFEX) && (IF_AD[1:0] == 2'b00))
if ((NEXT_STATE == `S_IFEX) && (IF_AD[1] == 1'b0))
SEL_PREV <= 4'b1111;
//else if ((NEXT_STATE == `S_IFEX) && (IF_AD[1:0] == 2'b10))
else if ((NEXT_STATE == `S_IFEX) && (IF_AD[1] == 1'b1))
SEL_PREV <= 4'b0011;
else
if (NEXT_STATE[1] == 1'b1)
begin
if (MA_SZ == 2'b10)
SEL_PREV <= 4'b1111;
else if ((MA_SZ == 2'b01) && (MA_AD[1] == 1'b0))
SEL_PREV <= 4'b1100;
else if ((MA_SZ == 2'b01) && (MA_AD[1] == 1'b1))
SEL_PREV <= 4'b0011;
else if ((MA_SZ == 2'b00) && (MA_AD[1:0] == 2'b00))
SEL_PREV <= 4'b1000;
else if ((MA_SZ == 2'b00) && (MA_AD[1:0] == 2'b01))
SEL_PREV <= 4'b0100;
else if ((MA_SZ == 2'b00) && (MA_AD[1:0] == 2'b10))
SEL_PREV <= 4'b0010;
else //if ((MA_SZ == 2'b00) && (MA_AD[1:0] == 2'b11))
SEL_PREV <= 4'b0001;
end
else SEL_PREV <= 4'b0000;
end
// output
always @(posedge CLK) begin
if ((NXTBUS == 1'b1) && (MEMEND == 1'b1)) begin
SEL <= SEL_PREV;
end
end
//======================================================
endmodule
//======================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -