mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Partial implementation of SDC AHBLite interface.
This commit is contained in:
parent
0f7be5e591
commit
9ed7a1f494
@ -55,9 +55,27 @@ module SDC
|
||||
logic initTrans;
|
||||
logic RegRead;
|
||||
logic RegWrite;
|
||||
logic [4:0] HADDRDelay;
|
||||
|
||||
// *** reduce size later
|
||||
|
||||
// Register outputs
|
||||
logic [31:0] CLKDiv;
|
||||
logic [2:0] Command;
|
||||
logic [`XLEN-1:9] Address;
|
||||
|
||||
|
||||
logic SDCDone;
|
||||
|
||||
logic [2:0] ErrorCode;
|
||||
logic InvalidCommand;
|
||||
logic Done;
|
||||
logic Busy;
|
||||
|
||||
logic StartCLKDivUpdate;
|
||||
logic CLKDivUpdateEn;
|
||||
logic SDCLKEN;
|
||||
|
||||
|
||||
|
||||
|
||||
// registers
|
||||
@ -68,7 +86,24 @@ module SDC
|
||||
//| 0x8 | Control | 4 | Send commands to SDC |
|
||||
//| 0xC | Size | 4 | Size of data command (only 512 byte supported) |
|
||||
//| 0x10 | address | 8 | address of operation |
|
||||
//| 0x18 | data | 8 | Data Bus interface |
|
||||
//| 0x18 | data | 8 | Data Bus interface |
|
||||
|
||||
// Status contains
|
||||
// Status[0] busy
|
||||
// Status[1] done
|
||||
// Status[2] invalid command
|
||||
// Status[5:3] error code
|
||||
|
||||
// control contains 3 bit command
|
||||
// control[2:0]
|
||||
// 000 nop op
|
||||
// xx1 initialize
|
||||
// 010 Write no implemented
|
||||
// 100 Read
|
||||
// 110 Atomic read/write not implemented
|
||||
|
||||
// size is fixed to 512. Read only
|
||||
|
||||
|
||||
// Currently using a mailbox style interface. Data is passed through the Data register (0x10)
|
||||
// The card will support 3 operations
|
||||
@ -81,12 +116,114 @@ module SDC
|
||||
|
||||
// currently does not support writes
|
||||
|
||||
assign InitTrans = HREADY & HSELTSDC & (HTRANS != 2'b00);
|
||||
assign RegWrite = InitTrans & HWRITE;
|
||||
assign RegRead = InitTrans & ~HWRITE;
|
||||
assign InitTrans = HREADY & HSELSDC & (HTRANS != 2'b00);
|
||||
assign RegRead = InitTrans & ~HWRITE;
|
||||
// AHBLite Spec has write data 1 cycle after write command
|
||||
flopr #(1) RegWriteReg(HCLK, ~HRESETn, InitTrans & HWRITE, RegWrite);
|
||||
|
||||
flopr #(5) HADDRReg(HCLK, ~HRESETn, HADDR, HADDRDelay);
|
||||
|
||||
assign StartCLKDivUpdate = HADDRDelay == '0 & RegWrite;
|
||||
|
||||
flopenl #(32) CLKDivReg(HCLK, ~HRESETn, CLKDivUpdateEn, HWDATA[31:0], `SDCCLKDIV, CLKDiv);
|
||||
|
||||
// *** need to delay
|
||||
flopenl #(32) CLKDivReg(HCLK, ~HRESETn, , HADDR == '0 & RegWrite, HWRITE, `SDCCLKDIV, CLKDiv);
|
||||
// Control reg
|
||||
flopenl #(3) CommandReg(HCLK, ~HRESETn, (HADDRDelay == 'h8 & RegWrite) | (SDCDone),
|
||||
SDCDone ? '0 : HWDATA[2:0], '0, Command);
|
||||
|
||||
flopenr #(`XLEN-9) AddressReg(HCLK, ~HRESETn, (HADDRDelay == 'h10 & RegWrite),
|
||||
HWDATA[`XLEN-1:9], Address);
|
||||
|
||||
flopen #(`XLEN) DataReg(HCLK, (HADDRDelay == 'h18 & RegWrite) | (SDCDataValid),
|
||||
SDCDataValid ? SDCReadData : HWDATA, ReadData);
|
||||
|
||||
generate
|
||||
if(`XLEN == 64) begin
|
||||
always_comb
|
||||
case(HADDRDelay[4:2])
|
||||
'h0: HREADSDC = {32'b0, CLKDiv};
|
||||
'h4: HREADSDC = {`XLEN-6'b0, ErrorCode, InvalidCommand, Done, Busy};
|
||||
'h8: HREADSDC = {`XLEN-3'b0, Command};
|
||||
'hC: HREADSDC = 'h200;
|
||||
'h10: HREADSDC = Address;
|
||||
'h18: HREADSDC = ReadData;
|
||||
default: HREADSDC = {32'b0, CLKDiv};
|
||||
endcase
|
||||
end else begin
|
||||
always_comb
|
||||
case(HADDRDelay[4:2])
|
||||
'h0: HREADSDC = CLKDiv;
|
||||
'h4: HREADSDC = {ErrorCode, InvalidCommand, Done, Busy};
|
||||
'h8: HREADSDC = Command;
|
||||
'hC: HREADSDC = 'h200;
|
||||
'h10: HREADSDC = Address[31:0];
|
||||
'h14: HREADSDC = Address[63:32];
|
||||
'h18: HREADSDC = ReadData[31:0];
|
||||
'h1C: HREADSDC = ReadData[63:32];
|
||||
default: HREADSDC = CLKDiv;
|
||||
endcase
|
||||
end
|
||||
endgenerate
|
||||
|
||||
typedef enum {STATE_READY,
|
||||
|
||||
// clock update states
|
||||
STATE_CLK_DIV1,
|
||||
STATE_CLK_DIV2,
|
||||
STATE_CLK_DIV3,
|
||||
STATE_CLK_DIV4,
|
||||
|
||||
// restart SDC
|
||||
STATE_RESTART,
|
||||
|
||||
// SDC operation
|
||||
STATE_PROCESS_CMD
|
||||
} statetype;
|
||||
|
||||
|
||||
statetype CurrState, NextState;
|
||||
|
||||
always_ff @(posedge HCLK, posedge ~HRESETn)
|
||||
if (~HRESETn) CurrState <= #1 STATE_READY;
|
||||
else CurrState <= #1 NextState;
|
||||
|
||||
always_comb begin
|
||||
CLKDivUpdateEn = 1'b0;
|
||||
HREADYSDC = 1'b0;
|
||||
SDCLKEN = 1'b1;
|
||||
case (CurrState)
|
||||
|
||||
STATE_READY : begin
|
||||
if (StartCLKDivUpdate)begin
|
||||
NextState = STATE_CLK_DIV1;
|
||||
HREADYSDC = 1'b0;
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
end else if () begin
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
end else begin
|
||||
NextState = STATE_READY;
|
||||
HREADYSDC = 1'b1;
|
||||
end
|
||||
end
|
||||
STATE_CLK_DIV1: begin
|
||||
NextState = STATE_CLK_DIV2;
|
||||
SDCLKEN = 1'b0;
|
||||
end
|
||||
STATE_CLK_DIV2: begin
|
||||
NextState = STATE_CLK_DIV3;
|
||||
CLKDivUpdateEn = 1'b1;
|
||||
SDCLKEN = 1'b0;
|
||||
end
|
||||
STATE_CLK_DIV3: begin
|
||||
NextState = STATE_CLK_DIV4;
|
||||
SDCLKEN = 1'b0;
|
||||
end
|
||||
STATE_CLK_DIV4: begin
|
||||
NextState = STATE_READY;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue
Block a user