Merge pull request #337 from harshinisrinath1001/main

Fixed the spacing of the uncore and wally modules
This commit is contained in:
David Harris 2023-06-15 11:33:29 -07:00 committed by GitHub
commit 8dbbf9201a
11 changed files with 375 additions and 374 deletions

View File

@ -31,11 +31,11 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn, input logic PCLK, PRESETn,
input logic PSEL, input logic PSEL,
input logic [15:0] PADDR, input logic [15:0] PADDR,
input logic [P.XLEN-1:0] PWDATA, input logic [P.XLEN-1:0] PWDATA,
input logic [P.XLEN/8-1:0] PSTRB, input logic [P.XLEN/8-1:0] PSTRB,
input logic PWRITE, input logic PWRITE,
input logic PENABLE, input logic PENABLE,
output logic [P.XLEN-1:0] PRDATA, output logic [P.XLEN-1:0] PRDATA,
output logic PREADY, output logic PREADY,
output logic [63:0] MTIME, output logic [63:0] MTIME,
output logic MTimerInt, MSwInt output logic MTimerInt, MSwInt
@ -48,11 +48,11 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
integer i, j; integer i, j;
assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase
assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond
// word aligned reads // word aligned reads
if (P.XLEN==64) assign #2 entry = {PADDR[15:3], 3'b000}; if (P.XLEN==64) assign #2 entry = {PADDR[15:3], 3'b000};
else assign #2 entry = {PADDR[15:2], 2'b00}; else assign #2 entry = {PADDR[15:2], 2'b00};
// DH 2/20/21: Eventually allow MTIME to run off a separate clock // DH 2/20/21: Eventually allow MTIME to run off a separate clock
// This will require synchronizing MTIME to the system clock // This will require synchronizing MTIME to the system clock
@ -150,36 +150,36 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
endmodule endmodule
module timeregsync import cvw::*; #(parameter cvw_t P) ( module timeregsync import cvw::*; #(parameter cvw_t P) (
input logic clk, resetn, input logic clk, resetn,
input logic we0, we1, input logic we0, we1,
input logic [P.XLEN-1:0] wd, input logic [P.XLEN-1:0] wd,
output logic [63:0] q); output logic [63:0] q);
if (P.XLEN==64) if (P.XLEN==64)
always_ff @(posedge clk or negedge resetn) always_ff @(posedge clk or negedge resetn)
if (~resetn) q <= 0; if (~resetn) q <= 0;
else if (we0) q <= wd; else if (we0) q <= wd;
else q <= q + 1; else q <= q + 1;
else else
always_ff @(posedge clk or negedge resetn) always_ff @(posedge clk or negedge resetn)
if (~resetn) q <= 0; if (~resetn) q <= 0;
else if (we0) q[31:0] <= wd; else if (we0) q[31:0] <= wd;
else if (we1) q[63:32] <= wd; else if (we1) q[63:32] <= wd;
else q <= q + 1; else q <= q + 1;
endmodule endmodule
module timereg import cvw::*; #(parameter cvw_t P) ( module timereg import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn, TIMECLK, input logic PCLK, PRESETn, TIMECLK,
input logic we0, we1, input logic we0, we1,
input logic [P.XLEN-1:0] PWDATA, input logic [P.XLEN-1:0] PWDATA,
output logic [63:0] MTIME, output logic [63:0] MTIME,
output logic done); output logic done);
// if (P.TIMEBASE_SYNC) begin:timereg // use PCLK for MTIME // if (P.TIMEBASE_SYNC) begin:timereg // use PCLK for MTIME
if (1) begin:timereg // use PCLK for MTIME if (1) begin:timereg // use PCLK for MTIME
timregsync timeregsync(.clk(PCLK), .resetn(PRESETn), .we0, .we1, .wd(PWDATA), .q(MTIME)); timregsync timeregsync(.clk(PCLK), .resetn(PRESETn), .we0, .we1, .wd(PWDATA), .q(MTIME));
assign done = 1; // immediately completes assign done = 1; // immediately completes
end else begin // use asynchronous TIMECLK end else begin // use asynchronous TIMECLK
// TIME counter runs on TIMECLK but bus interface runs on PCLK // TIME counter runs on TIMECLK but bus interface runs on PCLK
// Need to synchronize reads and writes // Need to synchronize reads and writes
// This is subtle because synchronizing a binary counter on a per-bit basis could give a mix of old and new bits // This is subtle because synchronizing a binary counter on a per-bit basis could give a mix of old and new bits

View File

@ -29,78 +29,78 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module gpio_apb import cvw::*; #(parameter cvw_t P) ( module gpio_apb import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn, input logic PCLK, PRESETn,
input logic PSEL, input logic PSEL,
input logic [7:0] PADDR, input logic [7:0] PADDR,
input logic [P.XLEN-1:0] PWDATA, input logic [P.XLEN-1:0] PWDATA,
input logic [P.XLEN/8-1:0] PSTRB, input logic [P.XLEN/8-1:0] PSTRB,
input logic PWRITE, input logic PWRITE,
input logic PENABLE, input logic PENABLE,
output logic [P.XLEN-1:0] PRDATA, output logic [P.XLEN-1:0] PRDATA,
output logic PREADY, output logic PREADY,
input logic [31:0] iof0, iof1, input logic [31:0] iof0, iof1,
input logic [31:0] GPIOIN, input logic [31:0] GPIOIN,
output logic [31:0] GPIOOUT, GPIOEN, output logic [31:0] GPIOOUT, GPIOEN,
output logic GPIOIntr output logic GPIOIntr
); );
logic [31:0] input0d, input1d, input2d, input3d; logic [31:0] input0d, input1d, input2d, input3d;
logic [31:0] input_val, input_en, output_en, output_val; logic [31:0] input_val, input_en, output_en, output_val;
logic [31:0] rise_ie, rise_ip, fall_ie, fall_ip, high_ie, high_ip, low_ie, low_ip; logic [31:0] rise_ie, rise_ip, fall_ie, fall_ip, high_ie, high_ip, low_ie, low_ip;
logic [31:0] out_xor, iof_en, iof_sel, iof_out, gpio_out; logic [31:0] out_xor, iof_en, iof_sel, iof_out, gpio_out;
logic [7:0] entry; logic [7:0] entry;
logic [31:0] Din, Dout; logic [31:0] Din, Dout;
logic memwrite; logic memwrite;
// APB I/O // APB I/O
assign entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses assign entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses
assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase
assign PREADY = 1'b1; // GPIO never takes >1 cycle to respond assign PREADY = 1'b1; // GPIO never takes >1 cycle to respond
// account for subword read/write circuitry // account for subword read/write circuitry
// -- Note GPIO registers are 32 bits no matter what; access them with LW SW. // -- Note GPIO registers are 32 bits no matter what; access them with LW SW.
// (At least that's what I think when FE310 spec says "only naturally aligned 32-bit accesses are supported") // (At least that's what I think when FE310 spec says "only naturally aligned 32-bit accesses are supported")
if (P.XLEN == 64) begin if (P.XLEN == 64) begin
assign Din = entry[2] ? PWDATA[63:32] : PWDATA[31:0]; assign Din = entry[2] ? PWDATA[63:32] : PWDATA[31:0];
assign PRDATA = entry[2] ? {Dout,32'b0} : {32'b0,Dout}; assign PRDATA = entry[2] ? {Dout,32'b0} : {32'b0,Dout};
end else begin // 32-bit end else begin // 32-bit
assign Din = PWDATA[31:0]; assign Din = PWDATA[31:0];
assign PRDATA = Dout; assign PRDATA = Dout;
end end
// register access // register access
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) begin // asynch reset if (~PRESETn) begin // asynch reset
input_en <= 0; input_en <= 0;
output_en <= 0; output_en <= 0;
// *** synch reset not yet implemented [DH: can we delete this comment? Check if a sync reset is required] // *** synch reset not yet implemented [DH: can we delete this comment? Check if a sync reset is required]
output_val <= #1 0; output_val <= #1 0;
rise_ie <= #1 0; rise_ie <= #1 0;
rise_ip <= #1 0; rise_ip <= #1 0;
fall_ie <= #1 0; fall_ie <= #1 0;
fall_ip <= #1 0; fall_ip <= #1 0;
high_ie <= #1 0; high_ie <= #1 0;
high_ip <= #1 0; high_ip <= #1 0;
low_ie <= #1 0; low_ie <= #1 0;
low_ip <= #1 0; low_ip <= #1 0;
iof_en <= #1 0; iof_en <= #1 0;
iof_sel <= #1 0; iof_sel <= #1 0;
out_xor <= #1 0; out_xor <= #1 0;
end else begin // writes end else begin // writes
// According to FE310 spec: Once the interrupt is pending, it will remain set until a 1 is written to the *_ip register at that bit. // According to FE310 spec: Once the interrupt is pending, it will remain set until a 1 is written to the *_ip register at that bit.
/* verilator lint_off CASEINCOMPLETE */ /* verilator lint_off CASEINCOMPLETE */
if (memwrite) if (memwrite)
case(entry) case(entry)
8'h04: input_en <= #1 Din; 8'h04: input_en <= #1 Din;
8'h08: output_en <= #1 Din; 8'h08: output_en <= #1 Din;
8'h0C: output_val <= #1 Din; 8'h0C: output_val <= #1 Din;
8'h18: rise_ie <= #1 Din; 8'h18: rise_ie <= #1 Din;
8'h20: fall_ie <= #1 Din; 8'h20: fall_ie <= #1 Din;
8'h28: high_ie <= #1 Din; 8'h28: high_ie <= #1 Din;
8'h30: low_ie <= #1 Din; 8'h30: low_ie <= #1 Din;
8'h38: iof_en <= #1 Din; 8'h38: iof_en <= #1 Din;
8'h3C: iof_sel <= #1 Din; 8'h3C: iof_sel <= #1 Din;
8'h40: out_xor <= #1 Din; 8'h40: out_xor <= #1 Din;
endcase endcase
/* verilator lint_on CASEINCOMPLETE */ /* verilator lint_on CASEINCOMPLETE */
@ -115,21 +115,21 @@ module gpio_apb import cvw::*; #(parameter cvw_t P) (
else low_ip <= low_ip | ~input3d; else low_ip <= low_ip | ~input3d;
case(entry) // flop to sample inputs case(entry) // flop to sample inputs
8'h00: Dout <= #1 input_val; 8'h00: Dout <= #1 input_val;
8'h04: Dout <= #1 input_en; 8'h04: Dout <= #1 input_en;
8'h08: Dout <= #1 output_en; 8'h08: Dout <= #1 output_en;
8'h0C: Dout <= #1 output_val; 8'h0C: Dout <= #1 output_val;
8'h18: Dout <= #1 rise_ie; 8'h18: Dout <= #1 rise_ie;
8'h1C: Dout <= #1 rise_ip; 8'h1C: Dout <= #1 rise_ip;
8'h20: Dout <= #1 fall_ie; 8'h20: Dout <= #1 fall_ie;
8'h24: Dout <= #1 fall_ip; 8'h24: Dout <= #1 fall_ip;
8'h28: Dout <= #1 high_ie; 8'h28: Dout <= #1 high_ie;
8'h2C: Dout <= #1 high_ip; 8'h2C: Dout <= #1 high_ip;
8'h30: Dout <= #1 low_ie; 8'h30: Dout <= #1 low_ie;
8'h34: Dout <= #1 low_ip; 8'h34: Dout <= #1 low_ip;
8'h38: Dout <= #1 iof_en; 8'h38: Dout <= #1 iof_en;
8'h3C: Dout <= #1 iof_sel; 8'h3C: Dout <= #1 iof_sel;
8'h40: Dout <= #1 out_xor; 8'h40: Dout <= #1 out_xor;
default: Dout <= #1 0; default: Dout <= #1 0;
endcase endcase
end end
@ -137,18 +137,17 @@ module gpio_apb import cvw::*; #(parameter cvw_t P) (
// chip i/o // chip i/o
// connect OUT to IN for loopback testing // connect OUT to IN for loopback testing
if (P.GPIO_LOOPBACK_TEST) assign input0d = ((output_en & GPIOOUT) | (~output_en & GPIOIN)) & input_en; if (P.GPIO_LOOPBACK_TEST) assign input0d = ((output_en & GPIOOUT) | (~output_en & GPIOIN)) & input_en;
else assign input0d = GPIOIN & input_en; else assign input0d = GPIOIN & input_en;
// synchroninzer for inputs // synchroninzer for inputs
flop #(32) sync1(PCLK,input0d,input1d); flop #(32) sync1(PCLK,input0d,input1d);
flop #(32) sync2(PCLK,input1d,input2d); flop #(32) sync2(PCLK,input1d,input2d);
flop #(32) sync3(PCLK,input2d,input3d); flop #(32) sync3(PCLK,input2d,input3d);
assign input_val = input3d; assign input_val = input3d;
assign iof_out = iof_sel & iof1 | ~iof_sel & iof0; // per-bit mux between iof1 and iof0 assign iof_out = iof_sel & iof1 | ~iof_sel & iof0; // per-bit mux between iof1 and iof0
assign gpio_out = iof_en & iof_out | ~iof_en & output_val; // per-bit mux between IOF and output_val assign gpio_out = iof_en & iof_out | ~iof_en & output_val; // per-bit mux between IOF and output_val
assign GPIOOUT = gpio_out ^ out_xor; // per-bit flip output polarity assign GPIOOUT = gpio_out ^ out_xor; // per-bit flip output polarity
assign GPIOEN = output_en; assign GPIOEN = output_en;
assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ie),(high_ip & high_ie),(low_ip & low_ie)}; assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ie),(high_ip & high_ie),(low_ip & low_ie)};
endmodule endmodule

View File

@ -41,22 +41,22 @@
// hardcoded to 2 contexts for now; later upgrade to arbitrary (up to 15872) contexts // hardcoded to 2 contexts for now; later upgrade to arbitrary (up to 15872) contexts
module plic_apb import cvw::*; #(parameter cvw_t P) ( module plic_apb import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn, input logic PCLK, PRESETn,
input logic PSEL, input logic PSEL,
input logic [27:0] PADDR, input logic [27:0] PADDR,
input logic [P.XLEN-1:0] PWDATA, input logic [P.XLEN-1:0] PWDATA,
input logic [P.XLEN/8-1:0] PSTRB, input logic [P.XLEN/8-1:0] PSTRB,
input logic PWRITE, input logic PWRITE,
input logic PENABLE, input logic PENABLE,
output logic [P.XLEN-1:0] PRDATA, output logic [P.XLEN-1:0] PRDATA,
output logic PREADY, output logic PREADY,
input logic UARTIntr,GPIOIntr, input logic UARTIntr,GPIOIntr,
output logic MExtInt, SExtInt output logic MExtInt, SExtInt
); );
logic memwrite, memread; logic memwrite, memread;
logic [23:0] entry; logic [23:0] entry;
logic [31:0] Din, Dout; logic [31:0] Din, Dout;
// context-independent signals // context-independent signals
logic [`N:1] requests; logic [`N:1] requests;
@ -78,9 +78,9 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
// ======= // =======
assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase
assign memread = ~PWRITE & PSEL; // read at start of access phase. PENABLE hasn't set up before this assign memread = ~PWRITE & PSEL; // read at start of access phase. PENABLE hasn't set up before this
assign PREADY = 1'b1; // PLIC never takes >1 cycle to respond assign PREADY = 1'b1; // PLIC never takes >1 cycle to respond
assign entry = {PADDR[23:2],2'b0}; assign entry = {PADDR[23:2],2'b0};
// account for subword read/write circuitry // account for subword read/write circuitry
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW. // -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
@ -97,6 +97,7 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
// ================== // ==================
// Register Interface // Register Interface
// ================== // ==================
always @(posedge PCLK) begin always @(posedge PCLK) begin
// resetting // resetting
if (~PRESETn) begin if (~PRESETn) begin
@ -110,19 +111,19 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
casez(entry) casez(entry)
24'h0000??: intPriority[entry[7:2]] <= #1 Din[2:0]; 24'h0000??: intPriority[entry[7:2]] <= #1 Din[2:0];
`ifdef PLIC_NUM_SRC_LT_32 // eventually switch to a generate for loop so as to deprecate PLIC_NUM_SRC_LT_32 and allow up to 1023 sources `ifdef PLIC_NUM_SRC_LT_32 // eventually switch to a generate for loop so as to deprecate PLIC_NUM_SRC_LT_32 and allow up to 1023 sources
24'h002000: intEn[0][`N:1] <= #1 Din[`N:1]; 24'h002000: intEn[0][`N:1] <= #1 Din[`N:1];
24'h002080: intEn[1][`N:1] <= #1 Din[`N:1]; 24'h002080: intEn[1][`N:1] <= #1 Din[`N:1];
`endif `endif
`ifndef PLIC_NUM_SRC_LT_32 `ifndef PLIC_NUM_SRC_LT_32
24'h002000: intEn[0][31:1] <= #1 Din[31:1]; 24'h002000: intEn[0][31:1] <= #1 Din[31:1];
24'h002004: intEn[0][`N:32] <= #1 Din[31:0]; 24'h002004: intEn[0][`N:32] <= #1 Din[31:0];
24'h002080: intEn[1][31:1] <= #1 Din[31:1]; 24'h002080: intEn[1][31:1] <= #1 Din[31:1];
24'h002084: intEn[1][`N:32] <= #1 Din[31:0]; 24'h002084: intEn[1][`N:32] <= #1 Din[31:0];
`endif `endif
24'h200000: intThreshold[0] <= #1 Din[2:0]; 24'h200000: intThreshold[0] <= #1 Din[2:0];
24'h200004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion 24'h200004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion
24'h201000: intThreshold[1] <= #1 Din[2:0]; 24'h201000: intThreshold[1] <= #1 Din[2:0];
24'h201004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion 24'h201004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion
endcase endcase
// Read synchronously because a read can have side effect of changing intInProgress // Read synchronously because a read can have side effect of changing intInProgress
if (memread) begin if (memread) begin
@ -245,4 +246,3 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
assign MExtInt = |(threshMask[0] & priorities_with_irqs[0]); assign MExtInt = |(threshMask[0] & priorities_with_irqs[0]);
assign SExtInt = |(threshMask[1] & priorities_with_irqs[1]); assign SExtInt = |(threshMask[1] & priorities_with_irqs[1]);
endmodule endmodule

View File

@ -30,33 +30,33 @@
module ram_ahb import cvw::*; #(parameter cvw_t P, module ram_ahb import cvw::*; #(parameter cvw_t P,
parameter BASE=0, RANGE = 65535) ( parameter BASE=0, RANGE = 65535) (
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
input logic HSELRam, input logic HSELRam,
input logic [P.PA_BITS-1:0] HADDR, input logic [P.PA_BITS-1:0] HADDR,
input logic HWRITE, input logic HWRITE,
input logic HREADY, input logic HREADY,
input logic [1:0] HTRANS, input logic [1:0] HTRANS,
input logic [P.XLEN-1:0] HWDATA, input logic [P.XLEN-1:0] HWDATA,
input logic [P.XLEN/8-1:0] HWSTRB, input logic [P.XLEN/8-1:0] HWSTRB,
output logic [P.XLEN-1:0] HREADRam, output logic [P.XLEN-1:0] HREADRam,
output logic HRESPRam, HREADYRam output logic HRESPRam, HREADYRam
); );
localparam ADDR_WIDTH = $clog2(RANGE/8); localparam ADDR_WIDTH = $clog2(RANGE/8);
localparam OFFSET = $clog2(P.XLEN/8); localparam OFFSET = $clog2(P.XLEN/8);
logic [P.XLEN/8-1:0] ByteMask; logic [P.XLEN/8-1:0] ByteMask;
logic [P.PA_BITS-1:0] HADDRD, RamAddr; logic [P.PA_BITS-1:0] HADDRD, RamAddr;
logic initTrans; logic initTrans;
logic memwrite, memwriteD, memread; logic memwrite, memwriteD, memread;
logic nextHREADYRam; logic nextHREADYRam;
logic DelayReady; logic DelayReady;
// a new AHB transactions starts when HTRANS requests a transaction, // a new AHB transactions starts when HTRANS requests a transaction,
// the peripheral is selected, and the previous transaction is completing // the peripheral is selected, and the previous transaction is completing
assign initTrans = HREADY & HSELRam & HTRANS[1] ; assign initTrans = HREADY & HSELRam & HTRANS[1] ;
assign memwrite = initTrans & HWRITE; assign memwrite = initTrans & HWRITE;
assign memread = initTrans & ~HWRITE; assign memread = initTrans & ~HWRITE;
flopenr #(1) memwritereg(HCLK, ~HRESETn, HREADY, memwrite, memwriteD); flopenr #(1) memwritereg(HCLK, ~HRESETn, HREADY, memwrite, memwriteD);
flopenr #(P.PA_BITS) haddrreg(HCLK, ~HRESETn, HREADY, HADDR, HADDRD); flopenr #(P.PA_BITS) haddrreg(HCLK, ~HRESETn, HREADY, HADDR, HADDRD);
@ -74,7 +74,6 @@ module ram_ahb import cvw::*; #(parameter cvw_t P,
ram1p1rwbe #(.DEPTH(RANGE/8), .WIDTH(P.XLEN)) memory(.clk(HCLK), .ce(1'b1), ram1p1rwbe #(.DEPTH(RANGE/8), .WIDTH(P.XLEN)) memory(.clk(HCLK), .ce(1'b1),
.addr(RamAddr[ADDR_WIDTH+OFFSET-1:OFFSET]), .we(memwriteD), .din(HWDATA), .bwe(HWSTRB), .dout(HREADRam)); .addr(RamAddr[ADDR_WIDTH+OFFSET-1:OFFSET]), .we(memwriteD), .din(HWDATA), .bwe(HWSTRB), .dout(HREADRam));
// use this to add arbitrary latency to ram. Helps test AHB controller correctness // use this to add arbitrary latency to ram. Helps test AHB controller correctness
if(`RAM_LATENCY > 0) begin if(`RAM_LATENCY > 0) begin
logic [7:0] NextCycle, Cycle; logic [7:0] NextCycle, Cycle;
@ -89,15 +88,15 @@ module ram_ahb import cvw::*; #(parameter cvw_t P,
always_ff @(posedge HCLK) always_ff @(posedge HCLK)
if (~HRESETn) CurrState <= #1 READY; if (~HRESETn) CurrState <= #1 READY;
else CurrState <= #1 NextState; else CurrState <= #1 NextState;
always_comb begin always_comb begin
case(CurrState) case(CurrState)
READY: if(initTrans & ~CycleFlag) NextState = DELAY; READY: if(initTrans & ~CycleFlag) NextState = DELAY;
else NextState = READY; else NextState = READY;
DELAY: if(CycleFlag) NextState = READY; DELAY: if(CycleFlag) NextState = READY;
else NextState = DELAY; else NextState = DELAY;
default: NextState = READY; default: NextState = READY;
endcase endcase
end end
@ -110,4 +109,3 @@ module ram_ahb import cvw::*; #(parameter cvw_t P,
end end
endmodule endmodule

View File

@ -28,24 +28,23 @@
module rom_ahb import cvw::*; #(parameter cvw_t P, module rom_ahb import cvw::*; #(parameter cvw_t P,
parameter BASE=0, RANGE = 65535) ( parameter BASE=0, RANGE = 65535) (
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
input logic HSELRom, input logic HSELRom,
input logic [P.PA_BITS-1:0] HADDR, input logic [P.PA_BITS-1:0] HADDR,
input logic HREADY, input logic HREADY,
input logic [1:0] HTRANS, input logic [1:0] HTRANS,
output logic [P.XLEN-1:0] HREADRom, output logic [P.XLEN-1:0] HREADRom,
output logic HRESPRom, HREADYRom output logic HRESPRom, HREADYRom
); );
localparam ADDR_WIDTH = $clog2(RANGE/8); localparam ADDR_WIDTH = $clog2(RANGE/8);
localparam OFFSET = $clog2(P.XLEN/8); localparam OFFSET = $clog2(P.XLEN/8);
// Never stalls // Never stalls
assign HREADYRom = 1'b1; assign HREADYRom = 1'b1;
assign HRESPRom = 0; // OK assign HRESPRom = 0; // OK
// single-ported ROM // single-ported ROM
rom1p1r #(ADDR_WIDTH, P.XLEN, P.FPGA) rom1p1r #(ADDR_WIDTH, P.XLEN, P.FPGA)
memory(.clk(HCLK), .ce(1'b1), .addr(HADDR[ADDR_WIDTH+OFFSET-1:OFFSET]), .dout(HREADRom)); memory(.clk(HCLK), .ce(1'b1), .addr(HADDR[ADDR_WIDTH+OFFSET-1:OFFSET]), .dout(HREADRom));
endmodule endmodule

View File

@ -45,7 +45,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
output logic INTR, TXRDYb, RXRDYb, // interrupt and ready lines output logic INTR, TXRDYb, RXRDYb, // interrupt and ready lines
// Clocks // Clocks
output logic BAUDOUTb, // active low baud clock output logic BAUDOUTb, // active low baud clock
input logic RCLK, // usually BAUDOUTb tied to RCLK externally input logic RCLK, // usually BAUDOUTb tied to RCLK externally
// E1A Driver // E1A Driver
input logic SIN, DSRb, DCDb, CTSb, RIb, // UART external serial and flow-control inputs input logic SIN, DSRb, DCDb, CTSb, RIb, // UART external serial and flow-control inputs
output logic SOUT, RTSb, DTRb, OUT1b, OUT2b // UART external serial and flow-control outputs output logic SOUT, RTSb, DTRb, OUT1b, OUT2b // UART external serial and flow-control outputs
@ -71,9 +71,9 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
logic DLAB; // Divisor Latch Access Bit (LCR bit 7) logic DLAB; // Divisor Latch Access Bit (LCR bit 7)
// Baud and rx/tx timing // Baud and rx/tx timing
logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period
logic [16+UART_PRESCALE-1:0] baudcount; logic [16+UART_PRESCALE-1:0] baudcount;
logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16 logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16
logic [3:0] rxbitsreceived, txbitssent; logic [3:0] rxbitsreceived, txbitssent;
statetype rxstate, txstate; statetype rxstate, txstate;
@ -122,6 +122,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
/////////////////////////////////////////// ///////////////////////////////////////////
// Input synchronization: 2-stage synchronizer // Input synchronization: 2-stage synchronizer
/////////////////////////////////////////// ///////////////////////////////////////////
always_ff @(posedge PCLK) begin always_ff @(posedge PCLK) begin
{SINd, DSRbd, DCDbd, CTSbd, RIbd} <= #1 {SIN, DSRb, DCDb, CTSb, RIb}; {SINd, DSRbd, DCDbd, CTSbd, RIbd} <= #1 {SIN, DSRb, DCDb, CTSb, RIb};
{SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync} <= #1 loop ? {SOUTbit, ~MCR[0], ~MCR[3], ~MCR[1], ~MCR[2]} : {SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync} <= #1 loop ? {SOUTbit, ~MCR[0], ~MCR[3], ~MCR[1], ~MCR[2]} :
@ -132,6 +133,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
/////////////////////////////////////////// ///////////////////////////////////////////
// Register interface (Table 1, note some are read only and some write only) // Register interface (Table 1, note some are read only and some write only)
/////////////////////////////////////////// ///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) begin // Table 3 Reset Configuration if (~PRESETn) begin // Table 3 Reset Configuration
IER <= #1 4'b0; IER <= #1 4'b0;
@ -162,13 +164,13 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
if (~MEMWb & (A == 3'b101)) if (~MEMWb & (A == 3'b101))
LSR[6:1] <= #1 Din[6:1]; // recommended only for test, see 8.6.3 LSR[6:1] <= #1 Din[6:1]; // recommended only for test, see 8.6.3
else begin else begin
LSR[0] <= #1 rxdataready; // Data ready LSR[0] <= #1 rxdataready; // Data ready
LSR[1] <= #1 (LSR[1] | RXBR[10]) & ~squashRXerrIP;; // overrun error LSR[1] <= #1 (LSR[1] | RXBR[10]) & ~squashRXerrIP;; // overrun error
LSR[2] <= #1 (LSR[2] | RXBR[9]) & ~squashRXerrIP; // parity error LSR[2] <= #1 (LSR[2] | RXBR[9]) & ~squashRXerrIP; // parity error
LSR[3] <= #1 (LSR[3] | RXBR[8]) & ~squashRXerrIP; // framing error LSR[3] <= #1 (LSR[3] | RXBR[8]) & ~squashRXerrIP; // framing error
LSR[4] <= #1 (LSR[4] | rxbreak) & ~squashRXerrIP; // break indicator LSR[4] <= #1 (LSR[4] | rxbreak) & ~squashRXerrIP; // break indicator
LSR[5] <= #1 THRE; // THRE LSR[5] <= #1 THRE; // THRE
LSR[6] <= #1 ~txsrfull & THRE; // TEMT LSR[6] <= #1 ~txsrfull & THRE; // TEMT
if (rxfifohaserr) LSR[7] <= #1 1; // any bits in FIFO have error if (rxfifohaserr) LSR[7] <= #1 1; // any bits in FIFO have error
end end
@ -208,6 +210,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
/////////////////////////////////////////// ///////////////////////////////////////////
// Ross Thompson: Found a bug. If the baud rate dividers DLM, and DLL are reloaded // Ross Thompson: Found a bug. If the baud rate dividers DLM, and DLL are reloaded
// the baudcount is not reset to {DLM, DLL, UART_PRESCALE} // the baudcount is not reset to {DLM, DLL, UART_PRESCALE}
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) begin if (~PRESETn) begin
baudcount <= #1 1; baudcount <= #1 1;
@ -233,17 +236,18 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
/////////////////////////////////////////// ///////////////////////////////////////////
// receive timing and control // receive timing and control
/////////////////////////////////////////// ///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) begin if (~PRESETn) begin
rxoversampledcnt <= #1 0; rxoversampledcnt <= #1 0;
rxstate <= #1 UART_IDLE; rxstate <= #1 UART_IDLE;
rxbitsreceived <= #1 0; rxbitsreceived <= #1 0;
rxtimeoutcnt <= #1 0; rxtimeoutcnt <= #1 0;
end else begin end else begin
if (rxstate == UART_IDLE & ~SINsync) begin // got start bit if (rxstate == UART_IDLE & ~SINsync) begin // got start bit
rxstate <= #1 UART_ACTIVE; rxstate <= #1 UART_ACTIVE;
rxoversampledcnt <= #1 0; rxoversampledcnt <= #1 0;
rxbitsreceived <= #1 0; rxbitsreceived <= #1 0;
if (~rxfifotimeout) rxtimeoutcnt <= #1 0; // reset timeout when new character is arriving. Jacob Pease: Only if the timeout was not already reached. p.16 PC16550D.pdf if (~rxfifotimeout) rxtimeoutcnt <= #1 0; // reset timeout when new character is arriving. Jacob Pease: Only if the timeout was not already reached. p.16 PC16550D.pdf
end else if (rxbaudpulse & (rxstate == UART_ACTIVE)) begin end else if (rxbaudpulse & (rxstate == UART_ACTIVE)) begin
rxoversampledcnt <= #1 rxoversampledcnt + 1; // 16x oversampled counter rxoversampledcnt <= #1 rxoversampledcnt + 1; // 16x oversampled counter
@ -260,13 +264,14 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
// ***explain why // ***explain why
if(QEMU) assign rxcentered = rxbaudpulse & (rxoversampledcnt[1:0] == 2'b10); // implies rxstate = UART_ACTIVE if(QEMU) assign rxcentered = rxbaudpulse & (rxoversampledcnt[1:0] == 2'b10); // implies rxstate = UART_ACTIVE
else assign rxcentered = rxbaudpulse & (rxoversampledcnt == 4'b1000); // implies rxstate = UART_ACTIVE else assign rxcentered = rxbaudpulse & (rxoversampledcnt == 4'b1000); // implies rxstate = UART_ACTIVE
assign rxbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1; // start bit + data bits + (parity bit) + stop bit assign rxbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1; // start bit + data bits + (parity bit) + stop bit
/////////////////////////////////////////// ///////////////////////////////////////////
// receive shift register, buffer register, FIFO // receive shift register, buffer register, FIFO
/////////////////////////////////////////// ///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) rxshiftreg <= #1 10'b0000000001; // initialize so that there is a valid stop bit if (~PRESETn) rxshiftreg <= #1 10'b0000000001; // initialize so that there is a valid stop bit
else if (rxcentered) rxshiftreg <= #1 {rxshiftreg[8:0], SINsync}; // capture bit else if (rxcentered) rxshiftreg <= #1 {rxshiftreg[8:0], SINsync}; // capture bit
@ -282,11 +287,11 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
assign rxdata = LCR[3] ? rxdata9[7:0] : rxdata9[8:1]; // discard parity bit assign rxdata = LCR[3] ? rxdata9[7:0] : rxdata9[8:1]; // discard parity bit
// ERROR CONDITIONS // ERROR CONDITIONS
assign rxparity = ^rxdata; assign rxparity = ^rxdata;
assign rxparityerr = (rxparity ^ rxparitybit ^ ~evenparitysel) & LCR[3]; // Check even/odd parity (*** check if LCR needs to be inverted) assign rxparityerr = (rxparity ^ rxparitybit ^ ~evenparitysel) & LCR[3]; // Check even/odd parity (*** check if LCR needs to be inverted)
assign rxoverrunerr = fifoenabled ? (rxfifoentries == 15) : rxdataready; // overrun if FIFO or receive buffer register full assign rxoverrunerr = fifoenabled ? (rxfifoentries == 15) : rxdataready; // overrun if FIFO or receive buffer register full
assign rxframingerr = ~rxstopbit; // framing error if no stop bit assign rxframingerr = ~rxstopbit; // framing error if no stop bit
assign rxbreak = rxframingerr & (rxdata9 == 9'b0); // break when 0 for start + data + parity + stop time assign rxbreak = rxframingerr & (rxdata9 == 9'b0); // break when 0 for start + data + parity + stop time
// receive FIFO and register // receive FIFO and register
always_ff @(posedge PCLK) always_ff @(posedge PCLK)
@ -298,7 +303,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
end else if (rxstate == UART_DONE) begin end else if (rxstate == UART_DONE) begin
RXBR <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; // load recevive buffer register RXBR <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; // load recevive buffer register
if (rxoverrunerr) $warning("UART RX Overrun Err\n"); if (rxoverrunerr) $warning("UART RX Overrun Err\n");
if (rxparityerr) $warning("UART RX Parity Err\n"); if (rxparityerr) $warning("UART RX Parity Err\n");
if (rxframingerr) $warning("UART RX Framing Err\n"); if (rxframingerr) $warning("UART RX Framing Err\n");
if (fifoenabled) begin if (fifoenabled) begin
rxfifo[rxfifohead] <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; rxfifo[rxfifohead] <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata};
@ -339,14 +344,14 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
else assign rxfullbitunwrapped[i] = ({1'b0,rxfifohead}==i | rxfullbitunwrapped[i-1]) & (rxfifotailunwrapped != i); else assign rxfullbitunwrapped[i] = ({1'b0,rxfifohead}==i | rxfullbitunwrapped[i-1]) & (rxfifotailunwrapped != i);
end end
for (i=0; i<16; i++) begin:rx for (i=0; i<16; i++) begin:rx
assign RXerrbit[i] = |rxfifo[i][10:8]; // are any of the error conditions set? assign RXerrbit[i] = |rxfifo[i][10:8]; // are any of the error conditions set?
assign rxfullbit[i] = rxfullbitunwrapped[i] | rxfullbitunwrapped[i+16]; assign rxfullbit[i] = rxfullbitunwrapped[i] | rxfullbitunwrapped[i+16];
/* if (i > 0) /* if (i > 0)
assign rxfullbit[i] = ((rxfifohead==i) | rxfullbit[i-1]) & (rxfifotail != i); assign rxfullbit[i] = ((rxfifohead==i) | rxfullbit[i-1]) & (rxfifotail != i);
else else
assign rxfullbit[0] = ((rxfifohead==i) | rxfullbit[15]) & (rxfifotail != i);*/ assign rxfullbit[0] = ((rxfifohead==i) | rxfullbit[15]) & (rxfifotail != i);*/
end end
assign rxfifohaserr = |(RXerrbit & rxfullbit); assign rxfifohaserr = |(RXerrbit & rxfullbit);
// receive buffer register and ready bit // receive buffer register and ready bit
always_ff @(posedge PCLK, negedge PRESETn) // track rxrdy for DMA mode (FCR3 = FCR0 = 1) always_ff @(posedge PCLK, negedge PRESETn) // track rxrdy for DMA mode (FCR3 = FCR0 = 1)
@ -361,22 +366,23 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
if (fifodmamodesel) RXRDYb = ~rxfifodmaready; if (fifodmamodesel) RXRDYb = ~rxfifodmaready;
else RXRDYb = rxfifoempty; else RXRDYb = rxfifoempty;
end else begin end else begin
RBR = RXBR; RBR = RXBR;
RXRDYb = ~rxdataready; RXRDYb = ~rxdataready;
end end
/////////////////////////////////////////// ///////////////////////////////////////////
// transmit timing and control // transmit timing and control
/////////////////////////////////////////// ///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) begin if (~PRESETn) begin
txoversampledcnt <= #1 0; txoversampledcnt <= #1 0;
txstate <= #1 UART_IDLE; txstate <= #1 UART_IDLE;
txbitssent <= #1 0; txbitssent <= #1 0;
end else if ((txstate == UART_IDLE) & txsrfull) begin // start transmitting end else if ((txstate == UART_IDLE) & txsrfull) begin // start transmitting
txstate <= #1 UART_ACTIVE; txstate <= #1 UART_ACTIVE;
txoversampledcnt <= #1 1; txoversampledcnt <= #1 1;
txbitssent <= #1 0; txbitssent <= #1 0;
end else if (txbaudpulse & (txstate == UART_ACTIVE)) begin end else if (txbaudpulse & (txstate == UART_ACTIVE)) begin
txoversampledcnt <= #1 txoversampledcnt + 1; txoversampledcnt <= #1 txoversampledcnt + 1;
if (txnextbit) begin // transmit at end of phase if (txnextbit) begin // transmit at end of phase
@ -390,11 +396,12 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
assign txbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1 + {3'b000, LCR[2]} - 4'd1; // start bit + data bits + (parity bit) + stop bit(s) - 1 assign txbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1 + {3'b000, LCR[2]} - 4'd1; // start bit + data bits + (parity bit) + stop bit(s) - 1
// *** explain; is this necessary? // *** explain; is this necessary?
if (QEMU) assign txnextbit = txbaudpulse & (txoversampledcnt[1:0] == 2'b00); // implies txstate = UART_ACTIVE if (QEMU) assign txnextbit = txbaudpulse & (txoversampledcnt[1:0] == 2'b00); // implies txstate = UART_ACTIVE
else assign txnextbit = txbaudpulse & (txoversampledcnt == 4'b0000); // implies txstate = UART_ACTIVE else assign txnextbit = txbaudpulse & (txoversampledcnt == 4'b0000); // implies txstate = UART_ACTIVE
/////////////////////////////////////////// ///////////////////////////////////////////
// transmit holding register, shift register, FIFO // transmit holding register, shift register, FIFO
/////////////////////////////////////////// ///////////////////////////////////////////
always_comb begin // compute value for parity and tx holding register always_comb begin // compute value for parity and tx holding register
nexttxdata = fifoenabled ? txfifo[txfifotail] : TXHR; // pick from FIFO or holding register nexttxdata = fifoenabled ? txfifo[txfifotail] : TXHR; // pick from FIFO or holding register
case (LCR[1:0]) // compute parity from appropriate number of bits case (LCR[1:0]) // compute parity from appropriate number of bits
@ -426,9 +433,9 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
if (~MEMWb & A == 3'b000 & ~DLAB) begin // writing transmit holding register or fifo if (~MEMWb & A == 3'b000 & ~DLAB) begin // writing transmit holding register or fifo
if (fifoenabled) begin if (fifoenabled) begin
txfifo[txfifohead] <= #1 Din; txfifo[txfifohead] <= #1 Din;
txfifohead <= #1 txfifohead + 1; txfifohead <= #1 txfifohead + 1;
end else begin end else begin
TXHR <= #1 Din; TXHR <= #1 Din;
txhrfull <= #1 1; txhrfull <= #1 1;
end end
$write("%c",Din); // for testbench $write("%c",Din); // for testbench
@ -436,12 +443,12 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
if (txstate == UART_IDLE) begin // move data into tx shift register if available if (txstate == UART_IDLE) begin // move data into tx shift register if available
if (fifoenabled) begin if (fifoenabled) begin
if (~txfifoempty & ~txsrfull) begin if (~txfifoempty & ~txsrfull) begin
txsr <= #1 txdata; txsr <= #1 txdata;
txfifotail <= #1 txfifotail+1; txfifotail <= #1 txfifotail+1;
txsrfull <= #1 1; txsrfull <= #1 1;
end end
end else if (txhrfull) begin end else if (txhrfull) begin
txsr <= #1 txdata; txsr <= #1 txdata;
txhrfull <= #1 0; txhrfull <= #1 0;
txsrfull <= #1 1; txsrfull <= #1 1;
end end
@ -470,13 +477,13 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
HeadPointerLastMove <= 1'b0; HeadPointerLastMove <= 1'b0;
end end
assign txfifoempty = (txfifohead == txfifotail) & ~HeadPointerLastMove; assign txfifoempty = (txfifohead == txfifotail) & ~HeadPointerLastMove;
// verilator lint_off WIDTH // verilator lint_off WIDTH
assign txfifoentries = (txfifohead >= txfifotail) ? (txfifohead-txfifotail) : assign txfifoentries = (txfifohead >= txfifotail) ? (txfifohead-txfifotail) :
(txfifohead + 16 - txfifotail); (txfifohead + 16 - txfifotail);
// verilator lint_on WIDTH // verilator lint_on WIDTH
//assign txfifofull = (txfifoentries == 4'b1111); //assign txfifofull = (txfifoentries == 4'b1111);
assign txfifofull = (txfifohead == txfifotail) & HeadPointerLastMove; assign txfifofull = (txfifohead == txfifotail) & HeadPointerLastMove;
// transmit buffer ready bit // transmit buffer ready bit
always_ff @(posedge PCLK, negedge PRESETn) // track txrdy for DMA mode (FCR3 = FCR0 = 1) always_ff @(posedge PCLK, negedge PRESETn) // track txrdy for DMA mode (FCR3 = FCR0 = 1)
@ -490,11 +497,12 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
// Transmitter pin // Transmitter pin
assign SOUTbit = txsr[11]; // transmit most significant bit assign SOUTbit = txsr[11]; // transmit most significant bit
assign SOUT = loop ? 1 : (LCR[6] ? 0 : SOUTbit); // tied to 1 during loopback or 0 during break assign SOUT = loop ? 1 : (LCR[6] ? 0 : SOUTbit); // tied to 1 during loopback or 0 during break
/////////////////////////////////////////// ///////////////////////////////////////////
// interrupts // interrupts
/////////////////////////////////////////// ///////////////////////////////////////////
assign RXerr = |LSR[4:1]; // LS interrupt if any of the flags are true assign RXerr = |LSR[4:1]; // LS interrupt if any of the flags are true
assign RXerrIP = RXerr & ~squashRXerrIP; // intr squashed upon reading LSR assign RXerrIP = RXerr & ~squashRXerrIP; // intr squashed upon reading LSR
assign rxdataavailintr = fifoenabled ? rxfifotriggered : rxdataready; assign rxdataavailintr = fifoenabled ? rxfifotriggered : rxdataready;
@ -533,15 +541,15 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
// modem control logic // modem control logic
/////////////////////////////////////////// ///////////////////////////////////////////
assign loop = MCR[4]; assign loop = MCR[4];
assign DTRb = ~MCR[0] | loop; // disable modem signals in loopback mode assign DTRb = ~MCR[0] | loop; // disable modem signals in loopback mode
assign RTSb = ~MCR[1] | loop; assign RTSb = ~MCR[1] | loop;
assign OUT1b = ~MCR[2] | loop; assign OUT1b = ~MCR[2] | loop;
assign OUT2b = ~MCR[3] | loop; assign OUT2b = ~MCR[3] | loop;
assign DLAB = LCR[7]; assign DLAB = LCR[7];
assign evenparitysel = LCR[4]; assign evenparitysel = LCR[4];
assign fifoenabled = FCR[0]; assign fifoenabled = FCR[0];
assign fifodmamodesel = FCR[3]; assign fifodmamodesel = FCR[3];
always_comb always_comb
case (FCR[7:6]) case (FCR[7:6])

View File

@ -29,18 +29,18 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module uart_apb import cvw::*; #(parameter cvw_t P) ( module uart_apb import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn, input logic PCLK, PRESETn,
input logic PSEL, input logic PSEL,
input logic [2:0] PADDR, input logic [2:0] PADDR,
input logic [P.XLEN-1:0] PWDATA, input logic [P.XLEN-1:0] PWDATA,
input logic [P.XLEN/8-1:0] PSTRB, input logic [P.XLEN/8-1:0] PSTRB,
input logic PWRITE, input logic PWRITE,
input logic PENABLE, input logic PENABLE,
output logic [P.XLEN-1:0] PRDATA, output logic [P.XLEN-1:0] PRDATA,
output logic PREADY, output logic PREADY,
input logic SIN, DSRb, DCDb, CTSb, RIb, // from E1A driver from RS232 interface input logic SIN, DSRb, DCDb, CTSb, RIb, // from E1A driver from RS232 interface
output logic SOUT, RTSb, DTRb, // to E1A driver to RS232 interface output logic SOUT, RTSb, DTRb, // to E1A driver to RS232 interface
output logic OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU output logic OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU
// UART interface signals // UART interface signals
logic [2:0] entry; logic [2:0] entry;
@ -49,10 +49,10 @@ module uart_apb import cvw::*; #(parameter cvw_t P) (
assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase
assign memread = ~PWRITE & PENABLE & PSEL; assign memread = ~PWRITE & PENABLE & PSEL;
assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond
assign entry = PADDR[2:0]; assign entry = PADDR[2:0];
assign MEMRb = ~memread; assign MEMRb = ~memread;
assign MEMWb = ~memwrite; assign MEMWb = ~memwrite;
if (P.XLEN == 64) begin:uart if (P.XLEN == 64) begin:uart
always_comb begin always_comb begin
@ -97,4 +97,3 @@ module uart_apb import cvw::*; #(parameter cvw_t P) (
); );
endmodule endmodule

View File

@ -29,58 +29,58 @@
module uncore import cvw::*; #(parameter cvw_t P)( module uncore import cvw::*; #(parameter cvw_t P)(
// AHB Bus Interface // AHB Bus Interface
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
input logic TIMECLK, input logic TIMECLK,
input logic [P.PA_BITS-1:0] HADDR, input logic [P.PA_BITS-1:0] HADDR,
input logic [P.AHBW-1:0] HWDATA, input logic [P.AHBW-1:0] HWDATA,
input logic [P.XLEN/8-1:0] HWSTRB, input logic [P.XLEN/8-1:0] HWSTRB,
input logic HWRITE, input logic HWRITE,
input logic [2:0] HSIZE, input logic [2:0] HSIZE,
input logic [2:0] HBURST, input logic [2:0] HBURST,
input logic [3:0] HPROT, input logic [3:0] HPROT,
input logic [1:0] HTRANS, input logic [1:0] HTRANS,
input logic HMASTLOCK, input logic HMASTLOCK,
input logic [P.AHBW-1:0] HRDATAEXT, input logic [P.AHBW-1:0] HRDATAEXT,
input logic HREADYEXT, HRESPEXT, input logic HREADYEXT, HRESPEXT,
output logic [P.AHBW-1:0] HRDATA, output logic [P.AHBW-1:0] HRDATA,
output logic HREADY, HRESP, output logic HREADY, HRESP,
output logic HSELEXT, output logic HSELEXT,
// peripheral pins // peripheral pins
output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT
output logic MExtInt, SExtInt, // External interrupts from PLIC output logic MExtInt, SExtInt, // External interrupts from PLIC
output logic [63:0] MTIME_CLINT, // MTIME, from CLINT output logic [63:0] MTIME_CLINT, // MTIME, from CLINT
input logic [31:0] GPIOIN, // GPIO pin input value input logic [31:0] GPIOIN, // GPIO pin input value
output logic [31:0] GPIOOUT, GPIOEN, // GPIO pin output value and enable output logic [31:0] GPIOOUT, GPIOEN, // GPIO pin output value and enable
input logic UARTSin, // UART serial input input logic UARTSin, // UART serial input
output logic UARTSout, // UART serial output output logic UARTSout, // UART serial output
output logic SDCCmdOut, // SD Card command output output logic SDCCmdOut, // SD Card command output
output logic SDCCmdOE, // SD Card command output enable output logic SDCCmdOE, // SD Card command output enable
input logic SDCCmdIn, // SD Card command input input logic SDCCmdIn, // SD Card command input
input logic [3:0] SDCDatIn, // SD Card data input input logic [3:0] SDCDatIn, // SD Card data input
output logic SDCCLK // SD Card clock output logic SDCCLK // SD Card clock
); );
logic [P.XLEN-1:0] HREADRam, HREADSDC; logic [P.XLEN-1:0] HREADRam, HREADSDC;
logic [10:0] HSELRegions; logic [10:0] HSELRegions;
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC; logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD; logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
logic HRESPRam, HRESPSDC; logic HRESPRam, HRESPSDC;
logic HREADYRam, HRESPSDCD; logic HREADYRam, HRESPSDCD;
logic [P.XLEN-1:0] HREADBootRom; logic [P.XLEN-1:0] HREADBootRom;
logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC; logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC;
logic HSELNoneD; logic HSELNoneD;
logic UARTIntr,GPIOIntr; logic UARTIntr,GPIOIntr;
logic SDCIntM; logic SDCIntM;
logic PCLK, PRESETn, PWRITE, PENABLE; logic PCLK, PRESETn, PWRITE, PENABLE;
logic [3:0] PSEL, PREADY; logic [3:0] PSEL, PREADY;
logic [31:0] PADDR; logic [31:0] PADDR;
logic [P.XLEN-1:0] PWDATA; logic [P.XLEN-1:0] PWDATA;
logic [P.XLEN/8-1:0] PSTRB; logic [P.XLEN/8-1:0] PSTRB;
logic [3:0][P.XLEN-1:0] PRDATA; logic [3:0][P.XLEN-1:0] PRDATA;
logic [P.XLEN-1:0] HREADBRIDGE; logic [P.XLEN-1:0] HREADBRIDGE;
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED; logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
// 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
@ -154,9 +154,9 @@ module uncore import cvw::*; #(parameter cvw_t P)(
.SDCIntM .SDCIntM
); );
end else begin : sdc end else begin : sdc
assign SDCCLK = 0; assign SDCCLK = 0;
assign SDCCmdOut = 0; assign SDCCmdOut = 0;
assign SDCCmdOE = 0; assign SDCCmdOE = 0;
end end
// AHB Read Multiplexer // AHB Read Multiplexer
@ -189,4 +189,3 @@ module uncore import cvw::*; #(parameter cvw_t P)(
HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD, HSELNoneD}); HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD, HSELNoneD});
flopenr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HREADY, HSELBRIDGE, HSELBRIDGED); flopenr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HREADY, HSELBRIDGE, HSELBRIDGED);
endmodule endmodule

View File

@ -68,31 +68,31 @@ typedef struct packed {
logic ICACHE_SUPPORTED; logic ICACHE_SUPPORTED;
// TLB configuration. Entries should be a power of 2 // TLB configuration. Entries should be a power of 2
int ITLB_ENTRIES; int ITLB_ENTRIES;
int DTLB_ENTRIES; int DTLB_ENTRIES;
// Cache configuration. Sizes should be a power of two // Cache configuration. Sizes should be a power of two
// typical configuration 4 ways, 4096 ints per way, 256 bit or more lines // typical configuration 4 ways, 4096 ints per way, 256 bit or more lines
int DCACHE_NUMWAYS; int DCACHE_NUMWAYS;
int DCACHE_WAYSIZEINBYTES; int DCACHE_WAYSIZEINBYTES;
int DCACHE_LINELENINBITS; int DCACHE_LINELENINBITS;
int ICACHE_NUMWAYS; int ICACHE_NUMWAYS;
int ICACHE_WAYSIZEINBYTES; int ICACHE_WAYSIZEINBYTES;
int ICACHE_LINELENINBITS; int ICACHE_LINELENINBITS;
// Integer Divider Configuration // Integer Divider Configuration
// IDIV_BITSPERCYCLE must be 1, 2, or 4 // IDIV_BITSPERCYCLE must be 1, 2, or 4
int IDIV_BITSPERCYCLE; int IDIV_BITSPERCYCLE;
logic IDIV_ON_FPU; logic IDIV_ON_FPU;
// Legal number of PMP entries are 0, 16, or 64 // Legal number of PMP entries are 0, 16, or 64
int PMP_ENTRIES; int PMP_ENTRIES;
// Address space // Address space
logic [63:0] RESET_VECTOR; logic [63:0] RESET_VECTOR;
// WFI Timeout Wait // WFI Timeout Wait
int WFI_TIMEOUT_BIT; int WFI_TIMEOUT_BIT;
// Peripheral Addresses // Peripheral Addresses
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
@ -134,24 +134,23 @@ typedef struct packed {
logic GPIO_LOOPBACK_TEST; logic GPIO_LOOPBACK_TEST;
// Hardware configuration // Hardware configuration
int UART_PRESCALE ; int UART_PRESCALE ;
// Interrupt configuration // Interrupt configuration
int PLIC_NUM_SRC; int PLIC_NUM_SRC;
logic PLIC_NUM_SRC_LT_32; logic PLIC_NUM_SRC_LT_32;
int PLIC_GPIO_ID; int PLIC_GPIO_ID;
int PLIC_UART_ID; int PLIC_UART_ID;
logic BPRED_SUPPORTED;
BranchPredictorType BPRED_TYPE;
int BPRED_NUM_LHR;
int BPRED_SIZE;
int BTB_SIZE;
logic BPRED_SUPPORTED;
BranchPredictorType BPRED_TYPE;
int BPRED_NUM_LHR;
int BPRED_SIZE;
int BTB_SIZE;
// FPU division architecture // FPU division architecture
int RADIX; int RADIX;
int DIVCOPIES; int DIVCOPIES;
// bit manipulation // bit manipulation
logic ZBA_SUPPORTED; logic ZBA_SUPPORTED;
@ -204,47 +203,47 @@ typedef struct packed {
int PMPCFG_ENTRIES; int PMPCFG_ENTRIES;
// Floating point constants for Quad, Double, Single, and Half precisions // Floating point constants for Quad, Double, Single, and Half precisions
int Q_LEN; int Q_LEN;
int Q_NE; int Q_NE;
int Q_NF; int Q_NF;
int Q_BIAS; int Q_BIAS;
logic [1:0] Q_FMT; logic [1:0] Q_FMT;
int D_LEN; int D_LEN;
int D_NE; int D_NE;
int D_NF; int D_NF;
int D_BIAS; int D_BIAS;
logic [1:0] D_FMT; logic [1:0] D_FMT;
int S_LEN; int S_LEN;
int S_NE; int S_NE;
int S_NF; int S_NF;
int S_BIAS; int S_BIAS;
logic [1:0] S_FMT; logic [1:0] S_FMT;
int H_LEN; int H_LEN;
int H_NE; int H_NE;
int H_NF; int H_NF;
int H_BIAS; int H_BIAS;
logic [1:0] H_FMT; logic [1:0] H_FMT;
// Floating point length FLEN and number of exponent (NE) and fraction (NF) bits // Floating point length FLEN and number of exponent (NE) and fraction (NF) bits
int FLEN; int FLEN;
int NE ; int NE ;
int NF ; int NF ;
logic [1:0] FMT ; logic [1:0] FMT ;
int BIAS; int BIAS;
// Floating point constants needed for FPU paramerterization // Floating point constants needed for FPU paramerterization
int FPSIZES; int FPSIZES;
int FMTBITS; int FMTBITS;
int LEN1 ; int LEN1 ;
int NE1 ; int NE1 ;
int NF1 ; int NF1 ;
logic [1:0] FMT1 ; logic [1:0] FMT1 ;
int BIAS1; int BIAS1;
int LEN2 ; int LEN2 ;
int NE2 ; int NE2 ;
int NF2 ; int NF2 ;
logic [1:0] FMT2 ; logic [1:0] FMT2 ;
int BIAS2; int BIAS2;
// largest length in IEU/FPU // largest length in IEU/FPU
int CVTLEN; int CVTLEN;
@ -256,7 +255,7 @@ typedef struct packed {
// division constants // division constants
int DIVN ; int DIVN ;
int LOGR; int LOGR ;
int RK ; int RK ;
int LOGRK ; int LOGRK ;
int FPDUR ; int FPDUR ;

View File

@ -32,12 +32,12 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
input logic MTimerInt, MExtInt, SExtInt, MSwInt, input logic MTimerInt, MExtInt, SExtInt, MSwInt,
input logic [63:0] MTIME_CLINT, input logic [63:0] MTIME_CLINT,
// Bus Interface // Bus Interface
input logic [P.AHBW-1:0] HRDATA, input logic [P.AHBW-1:0] HRDATA,
input logic HREADY, HRESP, input logic HREADY, HRESP,
output logic HCLK, HRESETn, output logic HCLK, HRESETn,
output logic [P.PA_BITS-1:0] HADDR, output logic [P.PA_BITS-1:0] HADDR,
output logic [P.AHBW-1:0] HWDATA, output logic [P.AHBW-1:0] HWDATA,
output logic [P.XLEN/8-1:0] HWSTRB, output logic [P.XLEN/8-1:0] HWSTRB,
output logic HWRITE, output logic HWRITE,
output logic [2:0] HSIZE, output logic [2:0] HSIZE,
output logic [2:0] HBURST, output logic [2:0] HBURST,
@ -55,15 +55,15 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic IntDivE, W64E; logic IntDivE, W64E;
logic CSRReadM, CSRWriteM, PrivilegedM; logic CSRReadM, CSRWriteM, PrivilegedM;
logic [1:0] AtomicM; logic [1:0] AtomicM;
logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE;
logic [P.XLEN-1:0] SrcAM; logic [P.XLEN-1:0] SrcAM;
logic [2:0] Funct3E; logic [2:0] Funct3E;
logic [31:0] InstrD; logic [31:0] InstrD;
logic [31:0] InstrM, InstrOrigM; logic [31:0] InstrM, InstrOrigM;
logic [P.XLEN-1:0] PCSpillF, PCE, PCLinkE; logic [P.XLEN-1:0] PCSpillF, PCE, PCLinkE;
logic [P.XLEN-1:0] PCM; logic [P.XLEN-1:0] PCM;
logic [P.XLEN-1:0] CSRReadValW, MDUResultW; logic [P.XLEN-1:0] CSRReadValW, MDUResultW;
logic [P.XLEN-1:0] UnalignedPCNextF, PC2NextF; logic [P.XLEN-1:0] UnalignedPCNextF, PC2NextF;
logic [1:0] MemRWM; logic [1:0] MemRWM;
logic InstrValidD, InstrValidE, InstrValidM; logic InstrValidD, InstrValidE, InstrValidM;
logic InstrMisalignedFaultM; logic InstrMisalignedFaultM;
@ -83,31 +83,31 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic [4:0] RdE, RdM, RdW; logic [4:0] RdE, RdM, RdW;
logic FPUStallD; logic FPUStallD;
logic FWriteIntE; logic FWriteIntE;
logic [P.FLEN-1:0] FWriteDataM; logic [P.FLEN-1:0] FWriteDataM;
logic [P.XLEN-1:0] FIntResM; logic [P.XLEN-1:0] FIntResM;
logic [P.XLEN-1:0] FCvtIntResW; logic [P.XLEN-1:0] FCvtIntResW;
logic FCvtIntW; logic FCvtIntW;
logic FDivBusyE; logic FDivBusyE;
logic FRegWriteM; logic FRegWriteM;
logic FCvtIntStallD; logic FCvtIntStallD;
logic FpLoadStoreM; logic FpLoadStoreM;
logic [4:0] SetFflagsM; logic [4:0] SetFflagsM;
logic [P.XLEN-1:0] FIntDivResultW; logic [P.XLEN-1:0] FIntDivResultW;
// memory management unit signals // memory management unit signals
logic ITLBWriteF; logic ITLBWriteF;
logic ITLBMissF; logic ITLBMissF;
logic [P.XLEN-1:0] SATP_REGW; logic [P.XLEN-1:0] SATP_REGW;
logic STATUS_MXR, STATUS_SUM, STATUS_MPRV; logic STATUS_MXR, STATUS_SUM, STATUS_MPRV;
logic [1:0] STATUS_MPP, STATUS_FS; logic [1:0] STATUS_MPP, STATUS_FS;
logic [1:0] PrivilegeModeW; logic [1:0] PrivilegeModeW;
logic [P.XLEN-1:0] PTE; logic [P.XLEN-1:0] PTE;
logic [1:0] PageType; logic [1:0] PageType;
logic sfencevmaM; logic sfencevmaM;
logic SelHPTW; logic SelHPTW;
// PMA checker signals // PMA checker signals
var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0]; var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0];
var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0]; var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0];
// IMem stalls // IMem stalls
@ -116,14 +116,14 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
// cpu lsu interface // cpu lsu interface
logic [2:0] Funct3M; logic [2:0] Funct3M;
logic [P.XLEN-1:0] IEUAdrE; logic [P.XLEN-1:0] IEUAdrE;
logic [P.XLEN-1:0] WriteDataM; logic [P.XLEN-1:0] WriteDataM;
logic [P.XLEN-1:0] IEUAdrM; logic [P.XLEN-1:0] IEUAdrM;
logic [P.LLEN-1:0] ReadDataW; logic [P.LLEN-1:0] ReadDataW;
logic CommittedM; logic CommittedM;
// AHB ifu interface // AHB ifu interface
logic [P.PA_BITS-1:0] IFUHADDR; logic [P.PA_BITS-1:0] IFUHADDR;
logic [2:0] IFUHBURST; logic [2:0] IFUHBURST;
logic [1:0] IFUHTRANS; logic [1:0] IFUHTRANS;
logic [2:0] IFUHSIZE; logic [2:0] IFUHSIZE;
@ -131,9 +131,9 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic IFUHREADY; logic IFUHREADY;
// AHB LSU interface // AHB LSU interface
logic [P.PA_BITS-1:0] LSUHADDR; logic [P.PA_BITS-1:0] LSUHADDR;
logic [P.XLEN-1:0] LSUHWDATA; logic [P.XLEN-1:0] LSUHWDATA;
logic [P.XLEN/8-1:0] LSUHWSTRB; logic [P.XLEN/8-1:0] LSUHWSTRB;
logic LSUHWRITE; logic LSUHWRITE;
logic LSUHREADY; logic LSUHREADY;
@ -192,12 +192,12 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.PCE, .PCLinkE, .FWriteIntE, .FCvtIntE, .IEUAdrE, .IntDivE, .W64E, .PCE, .PCLinkE, .FWriteIntE, .FCvtIntE, .IEUAdrE, .IntDivE, .W64E,
.Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .ForwardedSrcAE, .ForwardedSrcBE,
// Memory stage interface // Memory stage interface
.SquashSCW, // from LSU .SquashSCW, // from LSU
.MemRWM, // read/write control goes to LSU .MemRWM, // read/write control goes to LSU
.AtomicM, // atomic control goes to LSU .AtomicM, // atomic control goes to LSU
.WriteDataM, // Write data to LSU .WriteDataM, // Write data to LSU
.Funct3M, // size and signedness to LSU .Funct3M, // size and signedness to LSU
.SrcAM, // to privilege and fpu .SrcAM, // to privilege and fpu
.RdE, .RdM, .FIntResM, .FlushDCacheM, .RdE, .RdM, .FIntResM, .FlushDCacheM,
.BranchD, .BranchE, .JumpD, .JumpE, .BranchD, .BranchE, .JumpD, .JumpE,
// Writeback stage // Writeback stage
@ -219,24 +219,24 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.LSUHADDR, .HRDATA, .LSUHWDATA, .LSUHWSTRB, .LSUHSIZE, .LSUHADDR, .HRDATA, .LSUHWDATA, .LSUHWSTRB, .LSUHSIZE,
.LSUHBURST, .LSUHTRANS, .LSUHWRITE, .LSUHREADY, .LSUHBURST, .LSUHTRANS, .LSUHWRITE, .LSUHREADY,
// connect to csr or privilege and stay the same. // connect to csr or privilege and stay the same.
.PrivilegeModeW, .BigEndianM, // connects to csr .PrivilegeModeW, .BigEndianM, // connects to csr
.PMPCFG_ARRAY_REGW, // connects to csr .PMPCFG_ARRAY_REGW, // connects to csr
.PMPADDR_ARRAY_REGW, // connects to csr .PMPADDR_ARRAY_REGW, // connects to csr
// hptw keep i/o // hptw keep i/o
.SATP_REGW, // from csr .SATP_REGW, // from csr
.STATUS_MXR, // from csr .STATUS_MXR, // from csr
.STATUS_SUM, // from csr .STATUS_SUM, // from csr
.STATUS_MPRV, // from csr .STATUS_MPRV, // from csr
.STATUS_MPP, // from csr .STATUS_MPP, // from csr
.sfencevmaM, // connects to privilege .sfencevmaM, // connects to privilege
.DCacheStallM, // connects to privilege .DCacheStallM, // connects to privilege
.LoadPageFaultM, // connects to privilege .LoadPageFaultM, // connects to privilege
.StoreAmoPageFaultM, // connects to privilege .StoreAmoPageFaultM, // connects to privilege
.LoadMisalignedFaultM, // connects to privilege .LoadMisalignedFaultM, // connects to privilege
.LoadAccessFaultM, // connects to privilege .LoadAccessFaultM, // connects to privilege
.HPTWInstrAccessFaultF, // connects to privilege .HPTWInstrAccessFaultF, // connects to privilege
.StoreAmoMisalignedFaultM, // connects to privilege .StoreAmoMisalignedFaultM, // connects to privilege
.StoreAmoAccessFaultM, // connects to privilege .StoreAmoAccessFaultM, // connects to privilege
.InstrUpdateDAF, .InstrUpdateDAF,
.PCSpillF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW, .PCSpillF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW,
.LSUStallM); .LSUStallM);
@ -292,14 +292,14 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM); .FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM);
end else begin end else begin
assign CSRReadValW = 0; assign CSRReadValW = 0;
assign UnalignedPCNextF = PC2NextF; assign UnalignedPCNextF = PC2NextF;
assign RetM = 0; assign RetM = 0;
assign TrapM = 0; assign TrapM = 0;
assign wfiM = 0; assign wfiM = 0;
assign IntPendingM = 0; assign IntPendingM = 0;
assign sfencevmaM = 0; assign sfencevmaM = 0;
assign BigEndianM = 0; assign BigEndianM = 0;
end end
// multiply/divide unit // multiply/divide unit
@ -310,45 +310,45 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.MDUResultW, .DivBusyE); .MDUResultW, .DivBusyE);
end else begin // no M instructions supported end else begin // no M instructions supported
assign MDUResultW = 0; assign MDUResultW = 0;
assign DivBusyE = 0; assign DivBusyE = 0;
end end
// floating point unit // floating point unit
if (P.F_SUPPORTED) begin:fpu if (P.F_SUPPORTED) begin:fpu
fpu #(P) fpu( fpu #(P) fpu(
.clk, .reset, .clk, .reset,
.FRM_REGW, // Rounding mode from CSR .FRM_REGW, // Rounding mode from CSR
.InstrD, // instruction from IFU .InstrD, // instruction from IFU
.ReadDataW(ReadDataW[P.FLEN-1:0]),// Read data from memory .ReadDataW(ReadDataW[P.FLEN-1:0]), // Read data from memory
.ForwardedSrcAE, // Integer input being processed (from IEU) .ForwardedSrcAE, // Integer input being processed (from IEU)
.StallE, .StallM, .StallW, // stall signals from HZU .StallE, .StallM, .StallW, // stall signals from HZU
.FlushE, .FlushM, .FlushW, // flush signals from HZU .FlushE, .FlushM, .FlushW, // flush signals from HZU
.RdE, .RdM, .RdW, // which FP register to write to (from IEU) .RdE, .RdM, .RdW, // which FP register to write to (from IEU)
.STATUS_FS, // is floating-point enabled? .STATUS_FS, // is floating-point enabled?
.FRegWriteM, // FP register write enable .FRegWriteM, // FP register write enable
.FpLoadStoreM, .FpLoadStoreM,
.ForwardedSrcBE, // Integer input for intdiv .ForwardedSrcBE, // Integer input for intdiv
.Funct3E, .Funct3M, .IntDivE, .W64E, // Integer flags and functions .Funct3E, .Funct3M, .IntDivE, .W64E, // Integer flags and functions
.FPUStallD, // Stall the decode stage .FPUStallD, // Stall the decode stage
.FWriteIntE, .FCvtIntE, // integer register write enable, conversion operation .FWriteIntE, .FCvtIntE, // integer register write enable, conversion operation
.FWriteDataM, // Data to be written to memory .FWriteDataM, // Data to be written to memory
.FIntResM, // data to be written to integer register .FIntResM, // data to be written to integer register
.FCvtIntResW, // fp -> int conversion result to be stored in int register .FCvtIntResW, // fp -> int conversion result to be stored in int register
.FCvtIntW, // fpu result selection .FCvtIntW, // fpu result selection
.FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) .FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage)
.IllegalFPUInstrD, // Is the instruction an illegal fpu instruction .IllegalFPUInstrD, // Is the instruction an illegal fpu instruction
.SetFflagsM, // FPU flags (to privileged unit) .SetFflagsM, // FPU flags (to privileged unit)
.FIntDivResultW); .FIntDivResultW);
end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low
assign FPUStallD = 0; assign FPUStallD = 0;
assign FWriteIntE = 0; assign FWriteIntE = 0;
assign FCvtIntE = 0; assign FCvtIntE = 0;
assign FIntResM = 0; assign FIntResM = 0;
assign FCvtIntW = 0; assign FCvtIntW = 0;
assign FDivBusyE = 0; assign FDivBusyE = 0;
assign IllegalFPUInstrD = 1; assign IllegalFPUInstrD = 1;
assign SetFflagsM = 0; assign SetFflagsM = 0;
assign FpLoadStoreM = 0; assign FpLoadStoreM = 0;
end end
endmodule endmodule

View File

@ -51,9 +51,9 @@ module wallypipelinedsoc import cvw::*; (
output logic HREADY, output logic HREADY,
// I/O Interface // I/O Interface
input logic TIMECLK, // optional for CLINT MTIME counter input logic TIMECLK, // optional for CLINT MTIME counter
input logic [31:0] GPIOIN, // inputs from GPIO input logic [31:0] GPIOIN, // inputs from GPIO
output logic [31:0] GPIOOUT, // output values for GPIO output logic [31:0] GPIOOUT, // output values for GPIO
output logic [31:0] GPIOEN, // output enables for GPIO output logic [31:0] GPIOEN, // output enables for GPIO
input logic UARTSin, // UART serial data input input logic UARTSin, // UART serial data input
output logic UARTSout, // UART serial data output output logic UARTSout, // UART serial data output
input logic SDCCmdIn, // SDC Command input input logic SDCCmdIn, // SDC Command input