Found the ahb burst bug.

We had instruction fetches fixed HSIZE = 2 (4 bytes) for all requests.  It should be HSIZE = 3 (8 bytes) for cache fetches and 4 for uncached reads.  The reason this worked for non burst is the DDR4 memory controller returns the full double word even for 4 byte reads.  In burst mode the second beat ending up pointing to the next 4 bytes rather than the next 8 bytes.
This commit is contained in:
Ross Thompson 2022-09-17 20:30:01 -05:00
parent 9821a50eaa
commit cb34b7c98f
5 changed files with 31 additions and 29 deletions

View File

@ -34,7 +34,7 @@
`include "wally-config.vh" `include "wally-config.vh"
module ahbinterface #(parameter WRITEABLE = 0) module ahbinterface #(parameter WRITEABLE = 0) // **** modify to use LSU/ifu parameter to control widths of buses
( (
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
@ -57,6 +57,7 @@ module ahbinterface #(parameter WRITEABLE = 0)
logic CaptureEn; logic CaptureEn;
/// *** only 32 bit for IFU.
flopen #(`XLEN) fb(.clk(HCLK), .en(CaptureEn), .d(HRDATA), .q(ReadDataWord)); flopen #(`XLEN) fb(.clk(HCLK), .en(CaptureEn), .d(HRDATA), .q(ReadDataWord));
if(WRITEABLE) begin if(WRITEABLE) begin

View File

@ -41,6 +41,7 @@ module ahbmulticontroller
input logic clk, reset, input logic clk, reset,
// Signals from IFU // Signals from IFU
input logic [`PA_BITS-1:0] IFUHADDR, input logic [`PA_BITS-1:0] IFUHADDR,
input logic [2:0] IFUHSIZE,
input logic [2:0] IFUHBURST, input logic [2:0] IFUHBURST,
input logic [1:0] IFUHTRANS, input logic [1:0] IFUHTRANS,
output logic IFUHREADY, output logic IFUHREADY,
@ -69,28 +70,23 @@ module ahbmulticontroller
(* mark_debug = "true" *) output logic HMASTLOCK (* mark_debug = "true" *) output logic HMASTLOCK
); );
localparam ADRBITS = $clog2(`XLEN/8); // address bits for Byte Mask generator
typedef enum logic [1:0] {IDLE, ARBITRATE} statetype; typedef enum logic [1:0] {IDLE, ARBITRATE} statetype;
statetype CurrState, NextState; statetype CurrState, NextState;
logic LSUGrant;
logic [ADRBITS-1:0] HADDRD;
logic [1:0] HSIZED;
logic [1:0] save, restore, dis, sel; logic [1:0] save, restore, dis, sel;
logic both; logic both;
logic [`PA_BITS-1:0] IFUHADDRSave, IFUHADDROut; logic [`PA_BITS-1:0] IFUHADDROut;
logic [1:0] IFUHTRANSSave, IFUHTRANSOut; logic [1:0] IFUHTRANSOut;
logic [2:0] IFUHBURSTSave, IFUHBURSTOut; logic [2:0] IFUHBURSTOut;
logic [2:0] IFUHSIZEOut; logic [2:0] IFUHSIZEOut;
logic IFUHWRITEOut; logic IFUHWRITEOut;
logic [`PA_BITS-1:0] LSUHADDRSave, LSUHADDROut; logic [`PA_BITS-1:0] LSUHADDROut;
logic [1:0] LSUHTRANSSave, LSUHTRANSOut; logic [1:0] LSUHTRANSOut;
logic [2:0] LSUHBURSTSave, LSUHBURSTOut; logic [2:0] LSUHBURSTOut;
logic [2:0] LSUHSIZESave, LSUHSIZEOut; logic [2:0] LSUHSIZEOut;
logic LSUHWRITESave, LSUHWRITEOut; logic LSUHWRITEOut;
logic IFUReq, LSUReq; logic IFUReq, LSUReq;
logic IFUActive, LSUActive; logic IFUActive, LSUActive;
@ -112,7 +108,7 @@ module ahbmulticontroller
// input stage IFU // input stage IFU
controllerinputstage IFUInput(.HCLK, .HRESETn, .Save(save[0]), .Restore(restore[0]), .Disable(dis[0]), controllerinputstage IFUInput(.HCLK, .HRESETn, .Save(save[0]), .Restore(restore[0]), .Disable(dis[0]),
.Request(IFUReq), .Active(IFUActive), .Request(IFUReq), .Active(IFUActive),
.HWRITEin(1'b0), .HSIZEin(3'b010), .HBURSTin(IFUHBURST), .HTRANSin(IFUHTRANS), .HADDRin(IFUHADDR), .HWRITEin(1'b0), .HSIZEin(IFUHSIZE), .HBURSTin(IFUHBURST), .HTRANSin(IFUHTRANS), .HADDRin(IFUHADDR),
.HWRITEOut(IFUHWRITEOut), .HSIZEOut(IFUHSIZEOut), .HBURSTOut(IFUHBURSTOut), .HREADYOut(IFUHREADY), .HWRITEOut(IFUHWRITEOut), .HSIZEOut(IFUHSIZEOut), .HBURSTOut(IFUHBURSTOut), .HREADYOut(IFUHREADY),
.HTRANSOut(IFUHTRANSOut), .HADDROut(IFUHADDROut), .HREADYin(HREADY)); .HTRANSOut(IFUHTRANSOut), .HADDROut(IFUHADDROut), .HREADYin(HREADY));
@ -125,7 +121,7 @@ module ahbmulticontroller
// output mux //*** rewrite for general number of controllers. // output mux //*** rewrite for general number of controllers.
assign HADDR = sel[1] ? LSUHADDROut : sel[0] ? IFUHADDROut : '0; assign HADDR = sel[1] ? LSUHADDROut : sel[0] ? IFUHADDROut : '0;
assign HSIZE = sel[1] ? LSUHSIZEOut : sel[0] ? 3'b010: '0; // Instruction reads are always 32 bits assign HSIZE = sel[1] ? LSUHSIZEOut : sel[0] ? IFUHSIZEOut: '0;
assign HBURST = sel[1] ? LSUHBURSTOut : sel[0] ? IFUHBURSTOut : '0; // If doing memory accesses, use LSUburst, else use Instruction burst. assign HBURST = sel[1] ? LSUHBURSTOut : sel[0] ? IFUHBURSTOut : '0; // If doing memory accesses, use LSUburst, else use Instruction burst.
assign HTRANS = sel[1] ? LSUHTRANSOut : sel[0] ? IFUHTRANSOut: '0; // SEQ if not first read or write, NONSEQ if first read or write, IDLE otherwise assign HTRANS = sel[1] ? LSUHTRANSOut : sel[0] ? IFUHTRANSOut: '0; // SEQ if not first read or write, NONSEQ if first read or write, IDLE otherwise
assign HWRITE = sel[1] ? LSUHWRITEOut : sel[0] ? 1'b0 : '0; assign HWRITE = sel[1] ? LSUHWRITEOut : sel[0] ? 1'b0 : '0;

View File

@ -41,6 +41,7 @@ module ifu (
(* mark_debug = "true" *) output logic IFUStallF, (* mark_debug = "true" *) output logic IFUStallF,
(* mark_debug = "true" *) output logic [2:0] IFUHBURST, (* mark_debug = "true" *) output logic [2:0] IFUHBURST,
(* mark_debug = "true" *) output logic [1:0] IFUHTRANS, (* mark_debug = "true" *) output logic [1:0] IFUHTRANS,
(* mark_debug = "true" *) output logic [2:0] IFUHSIZE,
(* mark_debug = "true" *) output logic IFUHWRITE, (* mark_debug = "true" *) output logic IFUHWRITE,
(* mark_debug = "true" *) input logic IFUHREADY, (* mark_debug = "true" *) input logic IFUHREADY,
(* mark_debug = "true" *) output logic [`XLEN-1:0] PCF, (* mark_debug = "true" *) output logic [`XLEN-1:0] PCF,
@ -234,7 +235,7 @@ module ifu (
ahbcacheinterface #(WORDSPERLINE, LINELEN, LOGBWPL, `ICACHE) ahbcacheinterface #(WORDSPERLINE, LINELEN, LOGBWPL, `ICACHE)
ahbcacheinterface(.HCLK(clk), .HRESETn(~reset), ahbcacheinterface(.HCLK(clk), .HRESETn(~reset),
.HRDATA, .HRDATA,
.CacheRW, .HSIZE(), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .CacheRW, .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS),
.Funct3(3'b010), .HADDR(IFUHADDR), .HREADY(IFUHREADY), .HWRITE(IFUHWRITE), .CacheBusAdr(ICacheBusAdr), .Funct3(3'b010), .HADDR(IFUHADDR), .HREADY(IFUHREADY), .HWRITE(IFUHWRITE), .CacheBusAdr(ICacheBusAdr),
.WordCount(), .SelUncachedAdr, .SelBusWord(), .WordCount(), .SelUncachedAdr, .SelBusWord(),
.CacheBusAck(ICacheBusAck), .CacheBusAck(ICacheBusAck),
@ -249,6 +250,7 @@ module ifu (
logic CaptureEn; logic CaptureEn;
logic [1:0] RW; logic [1:0] RW;
assign RW = NonIROMMemRWM & ~{ITLBMissF, ITLBMissF}; assign RW = NonIROMMemRWM & ~{ITLBMissF, ITLBMissF};
assign IFUHSIZE = 3'b010;
ahbinterface #(0) ahbinterface(.HCLK(clk), .HRESETn(~reset), .HREADY(IFUHREADY), ahbinterface #(0) ahbinterface(.HCLK(clk), .HRESETn(~reset), .HREADY(IFUHREADY),
.HRDATA(HRDATA), .HTRANS(IFUHTRANS), .HWRITE(IFUHWRITE), .HWDATA(), .HRDATA(HRDATA), .HTRANS(IFUHTRANS), .HWRITE(IFUHWRITE), .HWDATA(),

View File

@ -216,7 +216,8 @@ module lsu (
assign MemStage = CPUBusy | MemRWM[0] | reset; // 1 = M stage; 0 = E stage assign MemStage = CPUBusy | MemRWM[0] | reset; // 1 = M stage; 0 = E stage
assign DTIMAdr = MemStage ? IEUAdrExtM : IEUAdrExtE; // zero extend or contract to PA_BITS assign DTIMAdr = MemStage ? IEUAdrExtM : IEUAdrExtE; // zero extend or contract to PA_BITS
/* verilator lint_on WIDTH */ /* verilator lint_on WIDTH */
assign DTIMAccessRW = |MemRWM; assign DTIMAccessRW = |MemRWM;
// *** Ross remove this.
adrdec dtimdec(IEUAdrExtM, `DTIM_BASE, `DTIM_RANGE, `DTIM_SUPPORTED, DTIMAccessRW, 2'b10, 4'b1111, SelDTIM); // maybe we pull this out of the mmu? adrdec dtimdec(IEUAdrExtM, `DTIM_BASE, `DTIM_RANGE, `DTIM_SUPPORTED, DTIMAccessRW, 2'b10, 4'b1111, SelDTIM); // maybe we pull this out of the mmu?
//assign NonDTIMMemRWM = MemRWM & ~{2{SelDTIM}}; // disable access to bus-based memory map when DTIM is selected //assign NonDTIMMemRWM = MemRWM & ~{2{SelDTIM}}; // disable access to bus-based memory map when DTIM is selected
assign NonDTIMMemRWM = MemRWM; // *** fix assign NonDTIMMemRWM = MemRWM; // *** fix

View File

@ -132,18 +132,19 @@ module wallypipelinedcore (
logic CommittedM; logic CommittedM;
// AHB ifu interface // AHB ifu interface
logic [`PA_BITS-1:0] IFUHADDR; logic [`PA_BITS-1:0] IFUHADDR;
logic [2:0] IFUHBURST; logic [2:0] IFUHBURST;
logic [1:0] IFUHTRANS; logic [1:0] IFUHTRANS;
logic IFUHWRITE; logic [2:0] IFUHSIZE;
logic IFUHREADY; logic IFUHWRITE;
logic IFUHREADY;
// AHB LSU interface // AHB LSU interface
logic [`PA_BITS-1:0] LSUHADDR; logic [`PA_BITS-1:0] LSUHADDR;
logic [`XLEN-1:0] LSUHWDATA; logic [`XLEN-1:0] LSUHWDATA;
logic [`XLEN/8-1:0] LSUHWSTRB; logic [`XLEN/8-1:0] LSUHWSTRB;
logic LSUHWRITE; logic LSUHWRITE;
logic LSUHREADY; logic LSUHREADY;
logic BPPredWrongE; logic BPPredWrongE;
logic BPPredDirWrongM; logic BPPredDirWrongM;
@ -172,7 +173,7 @@ module wallypipelinedcore (
.FlushF, .FlushD, .FlushE, .FlushM, .FlushF, .FlushD, .FlushE, .FlushM,
// Fetch // Fetch
.HRDATA, .PCF, .IFUHADDR, .HRDATA, .PCF, .IFUHADDR,
.IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUHSIZE,
.IFUHREADY, .IFUHWRITE, .IFUHREADY, .IFUHWRITE,
.ICacheAccess, .ICacheMiss, .ICacheAccess, .ICacheMiss,
@ -295,6 +296,7 @@ module wallypipelinedcore (
.IFUHBURST, .IFUHBURST,
.IFUHTRANS, .IFUHTRANS,
.IFUHREADY, .IFUHREADY,
.IFUHSIZE,
// LSU interface // LSU interface
.LSUHADDR, .LSUHADDR,
.LSUHWDATA, .LSUHWDATA,