1
0
mirror of https://github.com/openhwgroup/cvw synced 2025-02-11 06:05:49 +00:00

SDC to ABHLite interface partially done.

Added SDC to adrdec and uncore.
This commit is contained in:
Ross Thompson 2021-09-24 10:45:09 -05:00
parent a182263b1c
commit 4256ef82b1
8 changed files with 120 additions and 66 deletions

View File

@ -93,6 +93,9 @@
`define PLIC_SUPPORTED 1'b1 `define PLIC_SUPPORTED 1'b1
`define PLIC_BASE 34'h0C000000 `define PLIC_BASE 34'h0C000000
`define PLIC_RANGE 34'h03FFFFFF `define PLIC_RANGE 34'h03FFFFFF
`define SDC_SUPPORTED 1'b1
`define SDC_BASE 34'h00012100
`define SDC_RANGE 34'h00000020
// Bus Interface width // Bus Interface width
`define AHBW 32 `define AHBW 32

View File

@ -97,6 +97,9 @@
`define PLIC_SUPPORTED 1'b1 `define PLIC_SUPPORTED 1'b1
`define PLIC_BASE 56'h0C000000 `define PLIC_BASE 56'h0C000000
`define PLIC_RANGE 56'h03FFFFFF `define PLIC_RANGE 56'h03FFFFFF
`define SDC_SUPPORTED 1'b1
`define SDC_BASE 56'h00012100
`define SDC_RANGE 56'h00000020
// Test modes // Test modes

View File

@ -30,19 +30,20 @@ module adrdecs (
input logic [`PA_BITS-1:0] PhysicalAddress, input logic [`PA_BITS-1:0] PhysicalAddress,
input logic AccessRW, AccessRX, AccessRWX, input logic AccessRW, AccessRX, AccessRWX,
input logic [1:0] Size, input logic [1:0] Size,
output logic [6:0] SelRegions output logic [7:0] SelRegions
); );
// Determine which region of physical memory (if any) is being accessed // Determine which region of physical memory (if any) is being accessed
// *** eventually uncomment Access signals // *** eventually uncomment Access signals
adrdec boottimdec(PhysicalAddress, `BOOTTIM_BASE, `BOOTTIM_RANGE, `BOOTTIM_SUPPORTED, /*1'b1*/AccessRX, Size, 4'b1111, SelRegions[5]); adrdec boottimdec(PhysicalAddress, `BOOTTIM_BASE, `BOOTTIM_RANGE, `BOOTTIM_SUPPORTED, /*1'b1*/AccessRX, Size, 4'b1111, SelRegions[6]);
adrdec timdec(PhysicalAddress, `TIM_BASE, `TIM_RANGE, `TIM_SUPPORTED, /*1'b1*/AccessRWX, Size, 4'b1111, SelRegions[4]); adrdec timdec(PhysicalAddress, `TIM_BASE, `TIM_RANGE, `TIM_SUPPORTED, /*1'b1*/AccessRWX, Size, 4'b1111, SelRegions[5]);
adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, 4'b1111, SelRegions[3]); adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, 4'b1111, SelRegions[4]);
adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[2]); adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[3]);
adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[1]); adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[2]);
adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[0]); adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[1]);
adrdec sdcdec(PhysicalAddress, `SDC_BASE, `SDC_RANGE, `SDC_SUPPORTED, AccessRW, Size, 4'b0011, SelRegions[0]);
assign SelRegions[6] = ~|(SelRegions[5:0]); assign SelRegions[7] = ~|(SelRegions[6:0]);
endmodule endmodule

View File

@ -45,7 +45,7 @@ module pmachecker (
logic PMAAccessFault; logic PMAAccessFault;
logic AccessRW, AccessRWX, AccessRX; logic AccessRW, AccessRWX, AccessRX;
logic [6:0] SelRegions; logic [7:0] SelRegions;
// Determine what type of access is being made // Determine what type of access is being made
assign AccessRW = ReadAccessM | WriteAccessM; assign AccessRW = ReadAccessM | WriteAccessM;
@ -61,7 +61,7 @@ module pmachecker (
assign AtomicAllowed = SelRegions[4]; assign AtomicAllowed = SelRegions[4];
// Detect access faults // Detect access faults
assign PMAAccessFault = SelRegions[6] & AccessRWX; assign PMAAccessFault = SelRegions[7] & AccessRWX;
assign PMAInstrAccessFaultF = ExecuteAccessF && PMAAccessFault; assign PMAInstrAccessFaultF = ExecuteAccessF && PMAAccessFault;
assign PMALoadAccessFaultM = ReadAccessM && PMAAccessFault; assign PMALoadAccessFaultM = ReadAccessM && PMAAccessFault;
assign PMAStoreAccessFaultM = WriteAccessM && PMAAccessFault; assign PMAStoreAccessFaultM = WriteAccessM && PMAAccessFault;

View File

@ -43,16 +43,16 @@ module SDC
//sd card interface //sd card interface
// place the tristate drivers at the top. this level // place the tristate drivers at the top. this level
// will use dedicated 1 direction ports. // will use dedicated 1 direction ports.
output logic SDCmdOut, output logic SDCCmdOut,
input logic SDCmdIn, input logic SDCCmdIn,
output logic SDCmdOE, output logic SDCCmdOE,
input logic SDDatIn, input logic [3:0] SDCDatIn,
output logic SDCLK, output logic SDCCLK,
// interrupt to PLIC // interrupt to PLIC
output logic SDCIntM); output logic SDCIntM);
logic initTrans; logic InitTrans;
logic RegRead; logic RegRead;
logic RegWrite; logic RegWrite;
logic [4:0] HADDRDelay; logic [4:0] HADDRDelay;
@ -61,7 +61,7 @@ module SDC
// Register outputs // Register outputs
logic [7:0] CLKDiv; logic [7:0] CLKDiv;
logic [2:0] Command; logic [2:0] Command;
logic [`XLEN-1:9] Address; logic [63:9] Address;
logic SDCDone; logic SDCDone;
@ -73,23 +73,26 @@ module SDC
logic StartCLKDivUpdate; logic StartCLKDivUpdate;
logic CLKDivUpdateEn; logic CLKDivUpdateEn;
logic SDCLKEN; logic SDCCLKEN;
logic CLKGate;
logic SDCDataValid;
logic [`XLEN-1:0] SDCReadData;
logic [`XLEN-1:0] ReadData;
// registers // registers
//| Offset | Name | Size | Purpose | //| Offset | Name | Size | Purpose |
//|--------+---------+------+------------------------------------------------| //|--------+---------+--------+------------------------------------------------|
//| 0x0 | CLKDiv | 4 | Divide HCLK to produce SDCLK | //| 0x0 | CLKDiv | 4 | Divide HCLK to produce SDCLK |
//| 0x4 | Status | 4 | Provide status to software | //| 0x4 | Status | 4 | Provide status to software |
//| 0x8 | Control | 4 | Send commands to SDC | //| 0x8 | Control | 4 | Send commands to SDC |
//| 0xC | Size | 4 | Size of data command (only 512 byte supported) | //| 0xC | Size | 4 | Size of data command (only 512 byte supported) |
//| 0x10 | address | 8 | address of operation | //| 0x10 | address | 8 | address of operation |
//| 0x18 | data | 8 | Data Bus interface | //| 0x18 | data | XLEN/8 | Data Bus interface |
// Status contains // Status contains
// Status[0] busy // Status[0] busy
// Status[1] done // Status[1] done
// Status[2] invalid command // Status[2] invalid command
// Status[5:3] error code // Status[5:3] error code
@ -125,14 +128,23 @@ module SDC
assign StartCLKDivUpdate = HADDRDelay == '0 & RegWrite; assign StartCLKDivUpdate = HADDRDelay == '0 & RegWrite;
flopenl #(8) CLKDivReg(HCLK, ~HRESETn, CLKDivUpdateEn, HWDATA[31:0], `SDCCLKDIV, CLKDiv); flopenl #(8) CLKDivReg(HCLK, ~HRESETn, CLKDivUpdateEn, HWDATA[7:0], `SDCCLKDIV, CLKDiv);
// Control reg // Control reg
flopenl #(3) CommandReg(HCLK, ~HRESETn, (HADDRDelay == 'h8 & RegWrite) | (SDCDone), flopenl #(3) CommandReg(HCLK, ~HRESETn, (HADDRDelay == 'h8 & RegWrite) | (SDCDone),
SDCDone ? '0 : HWDATA[2:0], '0, Command); SDCDone ? '0 : HWDATA[2:0], '0, Command);
flopenr #(`XLEN-9) AddressReg(HCLK, ~HRESETn, (HADDRDelay == 'h10 & RegWrite), generate
HWDATA[`XLEN-1:9], Address); if (`XLEN == 64) begin
flopenr #(64-9) AddressReg(HCLK, ~HRESETn, (HADDRDelay == 'h10 & RegWrite),
HWDATA[`XLEN-1:9], Address);
end else begin
flopenr #(32-9) AddressLowReg(HCLK, ~HRESETn, (HADDRDelay == 'h10 & RegWrite),
HWDATA[`XLEN-1:9], Address[31:9]);
flopenr #(32) AddressHighReg(HCLK, ~HRESETn, (HADDRDelay == 'h14 & RegWrite),
HWDATA, Address[63:32]);
end
endgenerate
flopen #(`XLEN) DataReg(HCLK, (HADDRDelay == 'h18 & RegWrite) | (SDCDataValid), flopen #(`XLEN) DataReg(HCLK, (HADDRDelay == 'h18 & RegWrite) | (SDCDataValid),
SDCDataValid ? SDCReadData : HWDATA, ReadData); SDCDataValid ? SDCReadData : HWDATA, ReadData);
@ -140,27 +152,26 @@ module SDC
generate generate
if(`XLEN == 64) begin if(`XLEN == 64) begin
always_comb always_comb
case(HADDRDelay[4:2]) case(HADDRDelay[4:0])
'h0: HREADSDC = {`XLEN-8'b0, CLKDiv}; 'h0: HREADSDC = {56'b0, CLKDiv};
'h4: HREADSDC = {`XLEN-6'b0, ErrorCode, InvalidCommand, Done, Busy}; 'h4: HREADSDC = {58'b0, ErrorCode, InvalidCommand, Done, Busy};
'h8: HREADSDC = {`XLEN-3'b0, Command}; 'h8: HREADSDC = {61'b0, Command};
'hC: HREADSDC = 'h200; 'hC: HREADSDC = 'h200;
'h10: HREADSDC = Address; 'h10: HREADSDC = {Address, 9'b0};
'h18: HREADSDC = ReadData; 'h18: HREADSDC = ReadData;
default: HREADSDC = {32'b0, CLKDiv}; default: HREADSDC = {56'b0, CLKDiv};
endcase endcase
end else begin end else begin
always_comb always_comb
case(HADDRDelay[4:2]) case(HADDRDelay[4:0])
'h0: HREADSDC = CLKDiv; 'h0: HREADSDC = {24'b0, CLKDiv};
'h4: HREADSDC = {ErrorCode, InvalidCommand, Done, Busy}; 'h4: HREADSDC = {26'b0, ErrorCode, InvalidCommand, Done, Busy};
'h8: HREADSDC = Command; 'h8: HREADSDC = {29'b0, Command};
'hC: HREADSDC = 'h200; 'hC: HREADSDC = 'h200;
'h10: HREADSDC = Address[31:0]; 'h10: HREADSDC = {Address[31:9], 9'b0};
'h14: HREADSDC = Address[63:32]; 'h14: HREADSDC = Address[63:32];
'h18: HREADSDC = ReadData[31:0]; 'h18: HREADSDC = ReadData[31:0];
'h1C: HREADSDC = ReadData[63:32]; default: HREADSDC = {24'b0, CLKDiv};
default: HREADSDC = CLKDiv;
endcase endcase
end end
endgenerate endgenerate
@ -190,7 +201,7 @@ module SDC
always_comb begin always_comb begin
CLKDivUpdateEn = 1'b0; CLKDivUpdateEn = 1'b0;
HREADYSDC = 1'b0; HREADYSDC = 1'b0;
SDCLKEN = 1'b1; SDCCLKEN = 1'b1;
case (CurrState) case (CurrState)
STATE_READY : begin STATE_READY : begin
@ -208,16 +219,16 @@ module SDC
end end
STATE_CLK_DIV1: begin STATE_CLK_DIV1: begin
NextState = STATE_CLK_DIV2; NextState = STATE_CLK_DIV2;
SDCLKEN = 1'b0; SDCCLKEN = 1'b0;
end end
STATE_CLK_DIV2: begin STATE_CLK_DIV2: begin
NextState = STATE_CLK_DIV3; NextState = STATE_CLK_DIV3;
CLKDivUpdateEn = 1'b1; CLKDivUpdateEn = 1'b1;
SDCLKEN = 1'b0; SDCCLKEN = 1'b0;
end end
STATE_CLK_DIV3: begin STATE_CLK_DIV3: begin
NextState = STATE_CLK_DIV4; NextState = STATE_CLK_DIV4;
SDCLKEN = 1'b0; SDCCLKEN = 1'b0;
end end
STATE_CLK_DIV4: begin STATE_CLK_DIV4: begin
NextState = STATE_READY; NextState = STATE_READY;
@ -227,7 +238,7 @@ module SDC
// clock generation divider // clock generation divider
clockgater clockgater(.E(SDCLKEN), clockgater clockgater(.E(SDCCLKEN),
.SE(1'b0), .SE(1'b0),
.CLK(HCLK), .CLK(HCLK),
.ECLK(CLKGate)); .ECLK(CLKGate));
@ -237,7 +248,7 @@ module SDC
.i_EN(CLKDiv != 'b1), .i_EN(CLKDiv != 'b1),
.i_CLK(CLKGate), .i_CLK(CLKGate),
.i_RST(~HRESETn), .i_RST(~HRESETn),
.o_CLK(CLKSDC)); .o_CLK(SDCCLK));

View File

@ -204,7 +204,9 @@ module sd_cmd_fsm
localparam logic [7:0] c_NCC_min = 8'd7; // counter_in localparam logic [7:0] c_NCC_min = 8'd7; // counter_in
localparam logic [7:0] c_NRC_min = 8'd8; // counter_in localparam logic [7:0] c_NRC_min = 8'd8; // counter_in
localparam logic [18:0] c_1000ms = 18'd400000; // ACMD41 timeout //localparam logic [18:0] c_1000ms = 18'd400000; // ACMD41 timeout
//*** BUG this value is too bit to fit into 19 bits.
localparam logic [18:0] c_1000ms = 18'd40000; // ACMD41 timeout
// command instruction type (opcode(6)) // command instruction type (opcode(6))
localparam c_CMD = 1'b0; localparam c_CMD = 1'b0;

View File

@ -56,22 +56,28 @@ module uncore (
output logic [31:0] GPIOPinsOut, GPIOPinsEn, output logic [31:0] GPIOPinsOut, GPIOPinsEn,
input logic UARTSin, input logic UARTSin,
output logic UARTSout, output logic UARTSout,
output logic SDCCmdOut,
output logic SDCCmdOE,
input logic SDCCmdIn,
input logic [3:0] SDCDatIn,
output logic SDCCLK,
output logic [63:0] MTIME_CLINT, MTIMECMP_CLINT output logic [63:0] MTIME_CLINT, MTIMECMP_CLINT
); );
logic [`XLEN-1:0] HWDATA; logic [`XLEN-1:0] HWDATA;
logic [`XLEN-1:0] HREADTim, HREADCLINT, HREADPLIC, HREADGPIO, HREADUART; logic [`XLEN-1:0] HREADTim, HREADCLINT, HREADPLIC, HREADGPIO, HREADUART, HREADSDC;
logic [6:0] HSELRegions; logic [7:0] HSELRegions;
logic HSELTim, HSELCLINT, HSELPLIC, HSELGPIO, PreHSELUART, HSELUART; logic HSELTim, HSELCLINT, HSELPLIC, HSELGPIO, PreHSELUART, HSELUART, HSELSDC;
logic HSELTimD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD; logic HSELTimD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
logic HRESPTim, HRESPCLINT, HRESPPLIC, HRESPGPIO, HRESPUART; logic HRESPTim, HRESPCLINT, HRESPPLIC, HRESPGPIO, HRESPUART, HRESPSDC;
logic HREADYTim, HREADYCLINT, HREADYPLIC, HREADYGPIO, HREADYUART; logic HREADYTim, HREADYCLINT, HREADYPLIC, HREADYGPIO, HREADYUART, HRESPSDCD;
logic [`XLEN-1:0] HREADBootTim; logic [`XLEN-1:0] HREADBootTim;
logic HSELBootTim, HSELBootTimD, HRESPBootTim, HREADYBootTim; logic HSELBootTim, HSELBootTimD, HRESPBootTim, HREADYBootTim, HREADYSDC;
logic HSELNoneD; logic HSELNoneD;
logic [1:0] MemRWboottim; logic [1:0] MemRWboottim;
logic UARTIntr,GPIOIntr; logic UARTIntr,GPIOIntr;
logic SDCIntM;
// Determine which region of physical memory (if any) is being accessed // Determine which region of physical memory (if any) is being accessed
// Use a trimmed down portion of the PMA checker - only the address decoders // Use a trimmed down portion of the PMA checker - only the address decoders
@ -79,7 +85,7 @@ module uncore (
adrdecs adrdecs({{(`PA_BITS-32){1'b0}}, HADDR}, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions); adrdecs adrdecs({{(`PA_BITS-32){1'b0}}, HADDR}, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions);
// unswizzle HSEL signals // unswizzle HSEL signals
assign {HSELBootTim, HSELTim, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC} = HSELRegions[5:0]; assign {HSELBootTim, HSELTim, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[6:0];
// subword accesses: converts HWDATAIN to HWDATA // subword accesses: converts HWDATAIN to HWDATA
subwordwrite sww(.*); subwordwrite sww(.*);
@ -115,6 +121,17 @@ module uncore (
end else begin : uart end else begin : uart
assign UARTSout = 0; assign UARTIntr = 0; assign UARTSout = 0; assign UARTIntr = 0;
end end
if (`SDC_SUPPORTED == 1) begin : sdc
SDC SDC(.HCLK, .HRESETn, .HSELSDC, .HADDR(HADDR[4:0]), .HWRITE, .HREADY, .HTRANS,
.HWDATA, .HREADSDC, .HRESPSDC, .HREADYSDC,
// sdc interface
.SDCCmdOut, .SDCCmdIn, .SDCCmdOE, .SDCDatIn, .SDCCLK,
// interrupt to PLIC
.SDCIntM
);
end else begin : uart
assign UARTSout = 0; assign UARTIntr = 0;
end
endgenerate endgenerate
// mux could also include external memory // mux could also include external memory
@ -124,22 +141,25 @@ module uncore (
({`XLEN{HSELPLICD}} & HREADPLIC) | ({`XLEN{HSELPLICD}} & HREADPLIC) |
({`XLEN{HSELGPIOD}} & HREADGPIO) | ({`XLEN{HSELGPIOD}} & HREADGPIO) |
({`XLEN{HSELBootTimD}} & HREADBootTim) | ({`XLEN{HSELBootTimD}} & HREADBootTim) |
({`XLEN{HSELUARTD}} & HREADUART); ({`XLEN{HSELUARTD}} & HREADUART) |
({`XLEN{HSELSDC}} & HREADSDC);
assign HRESP = HSELTimD & HRESPTim | assign HRESP = HSELTimD & HRESPTim |
HSELCLINTD & HRESPCLINT | HSELCLINTD & HRESPCLINT |
HSELPLICD & HRESPPLIC | HSELPLICD & HRESPPLIC |
HSELGPIOD & HRESPGPIO | HSELGPIOD & HRESPGPIO |
HSELBootTimD & HRESPBootTim | HSELBootTimD & HRESPBootTim |
HSELUARTD & HRESPUART; HSELUARTD & HRESPUART |
HSELSDC & HRESPSDC;
assign HREADY = HSELTimD & HREADYTim | assign HREADY = HSELTimD & HREADYTim |
HSELCLINTD & HREADYCLINT | HSELCLINTD & HREADYCLINT |
HSELPLICD & HREADYPLIC | HSELPLICD & HREADYPLIC |
HSELGPIOD & HREADYGPIO | HSELGPIOD & HREADYGPIO |
HSELBootTimD & HREADYBootTim | HSELBootTimD & HREADYBootTim |
HSELUARTD & HREADYUART | HSELUARTD & HREADYUART |
HSELSDCD & HREADYSDC |
HSELNoneD; // don't lock up the bus if no region is being accessed HSELNoneD; // don't lock up the bus if no region is being accessed
// Address Decoder Delay (figure 4-2 in spec) // Address Decoder Delay (figure 4-2 in spec)
flopr #(7) hseldelayreg(HCLK, ~HRESETn, HSELRegions, {HSELNoneD, HSELBootTimD, HSELTimD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD}); flopr #(8) hseldelayreg(HCLK, ~HRESETn, HSELRegions, {HSELNoneD, HSELBootTimD, HSELTimD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD});
endmodule endmodule

View File

@ -51,7 +51,10 @@ module wallypipelinedsoc (
input logic [31:0] GPIOPinsIn, input logic [31:0] GPIOPinsIn,
output logic [31:0] GPIOPinsOut, GPIOPinsEn, output logic [31:0] GPIOPinsOut, GPIOPinsEn,
input logic UARTSin, input logic UARTSin,
output logic UARTSout output logic UARTSout,
output tri1 SDCCmd,
input logic [3:0] SDCDat,
output logic SDCCLK
); );
// to instruction memory *** remove later // to instruction memory *** remove later
@ -71,6 +74,17 @@ module wallypipelinedsoc (
logic [15:0] rd2; // bogus, delete when real multicycle fetch works logic [15:0] rd2; // bogus, delete when real multicycle fetch works
logic [31:0] InstrF; logic [31:0] InstrF;
logic SDCCmdOut;
logic SDCCmdOE;
logic SDCCmdIn;
logic [3:0] SDCDatIn;
assign SDCCmd = SDCCmdOE ? SDCCmdOut : 1'bz;
assign SDCCmdIn = SDCCmd;
assign SDCDatIn = SDCDat; // when write supported this will be a tristate
// instantiate processor and memories // instantiate processor and memories
wallypipelinedhart hart(.*); wallypipelinedhart hart(.*);