mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge pull request #337 from harshinisrinath1001/main
Fixed the spacing of the uncore and wally modules
This commit is contained in:
commit
8dbbf9201a
@ -31,11 +31,11 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
|
||||
input logic PCLK, PRESETn,
|
||||
input logic PSEL,
|
||||
input logic [15:0] PADDR,
|
||||
input logic [P.XLEN-1:0] PWDATA,
|
||||
input logic [P.XLEN/8-1:0] PSTRB,
|
||||
input logic [P.XLEN-1:0] PWDATA,
|
||||
input logic [P.XLEN/8-1:0] PSTRB,
|
||||
input logic PWRITE,
|
||||
input logic PENABLE,
|
||||
output logic [P.XLEN-1:0] PRDATA,
|
||||
output logic [P.XLEN-1:0] PRDATA,
|
||||
output logic PREADY,
|
||||
output logic [63:0] MTIME,
|
||||
output logic MTimerInt, MSwInt
|
||||
@ -48,11 +48,11 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
|
||||
integer i, j;
|
||||
|
||||
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
|
||||
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
|
||||
// This will require synchronizing MTIME to the system clock
|
||||
@ -150,36 +150,36 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
|
||||
endmodule
|
||||
|
||||
module timeregsync import cvw::*; #(parameter cvw_t P) (
|
||||
input logic clk, resetn,
|
||||
input logic we0, we1,
|
||||
input logic clk, resetn,
|
||||
input logic we0, we1,
|
||||
input logic [P.XLEN-1:0] wd,
|
||||
output logic [63:0] q);
|
||||
output logic [63:0] q);
|
||||
|
||||
if (P.XLEN==64)
|
||||
always_ff @(posedge clk or negedge resetn)
|
||||
if (~resetn) q <= 0;
|
||||
if (~resetn) q <= 0;
|
||||
else if (we0) q <= wd;
|
||||
else q <= q + 1;
|
||||
else
|
||||
always_ff @(posedge clk or negedge resetn)
|
||||
if (~resetn) q <= 0;
|
||||
if (~resetn) q <= 0;
|
||||
else if (we0) q[31:0] <= wd;
|
||||
else if (we1) q[63:32] <= wd;
|
||||
else q <= q + 1;
|
||||
endmodule
|
||||
|
||||
module timereg import cvw::*; #(parameter cvw_t P) (
|
||||
input logic PCLK, PRESETn, TIMECLK,
|
||||
input logic we0, we1,
|
||||
input logic PCLK, PRESETn, TIMECLK,
|
||||
input logic we0, we1,
|
||||
input logic [P.XLEN-1:0] PWDATA,
|
||||
output logic [63:0] MTIME,
|
||||
output logic done);
|
||||
output logic [63:0] MTIME,
|
||||
output logic done);
|
||||
|
||||
// if (P.TIMEBASE_SYNC) 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));
|
||||
assign done = 1; // immediately completes
|
||||
end else begin // use asynchronous TIMECLK
|
||||
assign done = 1; // immediately completes
|
||||
end else begin // use asynchronous TIMECLK
|
||||
// TIME counter runs on TIMECLK but bus interface runs on PCLK
|
||||
// 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
|
||||
|
@ -29,78 +29,78 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module gpio_apb import cvw::*; #(parameter cvw_t P) (
|
||||
input logic PCLK, PRESETn,
|
||||
input logic PSEL,
|
||||
input logic [7:0] PADDR,
|
||||
input logic [P.XLEN-1:0] PWDATA,
|
||||
input logic PCLK, PRESETn,
|
||||
input logic PSEL,
|
||||
input logic [7:0] PADDR,
|
||||
input logic [P.XLEN-1:0] PWDATA,
|
||||
input logic [P.XLEN/8-1:0] PSTRB,
|
||||
input logic PWRITE,
|
||||
input logic PENABLE,
|
||||
output logic [P.XLEN-1:0] PRDATA,
|
||||
output logic PREADY,
|
||||
input logic [31:0] iof0, iof1,
|
||||
input logic [31:0] GPIOIN,
|
||||
output logic [31:0] GPIOOUT, GPIOEN,
|
||||
output logic GPIOIntr
|
||||
input logic PWRITE,
|
||||
input logic PENABLE,
|
||||
output logic [P.XLEN-1:0] PRDATA,
|
||||
output logic PREADY,
|
||||
input logic [31:0] iof0, iof1,
|
||||
input logic [31:0] GPIOIN,
|
||||
output logic [31:0] GPIOOUT, GPIOEN,
|
||||
output logic GPIOIntr
|
||||
);
|
||||
|
||||
logic [31:0] input0d, input1d, input2d, input3d;
|
||||
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] out_xor, iof_en, iof_sel, iof_out, gpio_out;
|
||||
logic [7:0] entry;
|
||||
logic [31:0] Din, Dout;
|
||||
logic memwrite;
|
||||
logic [31:0] input0d, input1d, input2d, input3d;
|
||||
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] out_xor, iof_en, iof_sel, iof_out, gpio_out;
|
||||
logic [7:0] entry;
|
||||
logic [31:0] Din, Dout;
|
||||
logic memwrite;
|
||||
|
||||
// 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 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
|
||||
// -- 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")
|
||||
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};
|
||||
end else begin // 32-bit
|
||||
assign Din = PWDATA[31:0];
|
||||
assign Din = PWDATA[31:0];
|
||||
assign PRDATA = Dout;
|
||||
end
|
||||
|
||||
// register access
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) begin // asynch reset
|
||||
input_en <= 0;
|
||||
input_en <= 0;
|
||||
output_en <= 0;
|
||||
// *** synch reset not yet implemented [DH: can we delete this comment? Check if a sync reset is required]
|
||||
output_val <= #1 0;
|
||||
rise_ie <= #1 0;
|
||||
rise_ip <= #1 0;
|
||||
fall_ie <= #1 0;
|
||||
fall_ip <= #1 0;
|
||||
high_ie <= #1 0;
|
||||
high_ip <= #1 0;
|
||||
low_ie <= #1 0;
|
||||
low_ip <= #1 0;
|
||||
iof_en <= #1 0;
|
||||
iof_sel <= #1 0;
|
||||
out_xor <= #1 0;
|
||||
rise_ie <= #1 0;
|
||||
rise_ip <= #1 0;
|
||||
fall_ie <= #1 0;
|
||||
fall_ip <= #1 0;
|
||||
high_ie <= #1 0;
|
||||
high_ip <= #1 0;
|
||||
low_ie <= #1 0;
|
||||
low_ip <= #1 0;
|
||||
iof_en <= #1 0;
|
||||
iof_sel <= #1 0;
|
||||
out_xor <= #1 0;
|
||||
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.
|
||||
/* verilator lint_off CASEINCOMPLETE */
|
||||
if (memwrite)
|
||||
case(entry)
|
||||
8'h04: input_en <= #1 Din;
|
||||
8'h08: output_en <= #1 Din;
|
||||
8'h04: input_en <= #1 Din;
|
||||
8'h08: output_en <= #1 Din;
|
||||
8'h0C: output_val <= #1 Din;
|
||||
8'h18: rise_ie <= #1 Din;
|
||||
8'h20: fall_ie <= #1 Din;
|
||||
8'h28: high_ie <= #1 Din;
|
||||
8'h30: low_ie <= #1 Din;
|
||||
8'h38: iof_en <= #1 Din;
|
||||
8'h3C: iof_sel <= #1 Din;
|
||||
8'h40: out_xor <= #1 Din;
|
||||
8'h18: rise_ie <= #1 Din;
|
||||
8'h20: fall_ie <= #1 Din;
|
||||
8'h28: high_ie <= #1 Din;
|
||||
8'h30: low_ie <= #1 Din;
|
||||
8'h38: iof_en <= #1 Din;
|
||||
8'h3C: iof_sel <= #1 Din;
|
||||
8'h40: out_xor <= #1 Din;
|
||||
endcase
|
||||
/* verilator lint_on CASEINCOMPLETE */
|
||||
|
||||
@ -115,21 +115,21 @@ module gpio_apb import cvw::*; #(parameter cvw_t P) (
|
||||
else low_ip <= low_ip | ~input3d;
|
||||
|
||||
case(entry) // flop to sample inputs
|
||||
8'h00: Dout <= #1 input_val;
|
||||
8'h04: Dout <= #1 input_en;
|
||||
8'h08: Dout <= #1 output_en;
|
||||
8'h0C: Dout <= #1 output_val;
|
||||
8'h18: Dout <= #1 rise_ie;
|
||||
8'h1C: Dout <= #1 rise_ip;
|
||||
8'h20: Dout <= #1 fall_ie;
|
||||
8'h24: Dout <= #1 fall_ip;
|
||||
8'h28: Dout <= #1 high_ie;
|
||||
8'h2C: Dout <= #1 high_ip;
|
||||
8'h30: Dout <= #1 low_ie;
|
||||
8'h34: Dout <= #1 low_ip;
|
||||
8'h38: Dout <= #1 iof_en;
|
||||
8'h3C: Dout <= #1 iof_sel;
|
||||
8'h40: Dout <= #1 out_xor;
|
||||
8'h00: Dout <= #1 input_val;
|
||||
8'h04: Dout <= #1 input_en;
|
||||
8'h08: Dout <= #1 output_en;
|
||||
8'h0C: Dout <= #1 output_val;
|
||||
8'h18: Dout <= #1 rise_ie;
|
||||
8'h1C: Dout <= #1 rise_ip;
|
||||
8'h20: Dout <= #1 fall_ie;
|
||||
8'h24: Dout <= #1 fall_ip;
|
||||
8'h28: Dout <= #1 high_ie;
|
||||
8'h2C: Dout <= #1 high_ip;
|
||||
8'h30: Dout <= #1 low_ie;
|
||||
8'h34: Dout <= #1 low_ip;
|
||||
8'h38: Dout <= #1 iof_en;
|
||||
8'h3C: Dout <= #1 iof_sel;
|
||||
8'h40: Dout <= #1 out_xor;
|
||||
default: Dout <= #1 0;
|
||||
endcase
|
||||
end
|
||||
@ -137,18 +137,17 @@ module gpio_apb import cvw::*; #(parameter cvw_t P) (
|
||||
// chip i/o
|
||||
// connect OUT to IN for loopback testing
|
||||
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
|
||||
flop #(32) sync1(PCLK,input0d,input1d);
|
||||
flop #(32) sync2(PCLK,input1d,input2d);
|
||||
flop #(32) sync3(PCLK,input2d,input3d);
|
||||
assign input_val = input3d;
|
||||
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 GPIOOUT = gpio_out ^ out_xor; // per-bit flip output polarity
|
||||
assign GPIOEN = output_en;
|
||||
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 GPIOOUT = gpio_out ^ out_xor; // per-bit flip output polarity
|
||||
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
|
||||
|
||||
|
@ -41,22 +41,22 @@
|
||||
// hardcoded to 2 contexts for now; later upgrade to arbitrary (up to 15872) contexts
|
||||
|
||||
module plic_apb import cvw::*; #(parameter cvw_t P) (
|
||||
input logic PCLK, PRESETn,
|
||||
input logic PSEL,
|
||||
input logic [27:0] PADDR,
|
||||
input logic PCLK, PRESETn,
|
||||
input logic PSEL,
|
||||
input logic [27:0] PADDR,
|
||||
input logic [P.XLEN-1:0] PWDATA,
|
||||
input logic [P.XLEN/8-1:0] PSTRB,
|
||||
input logic PWRITE,
|
||||
input logic PENABLE,
|
||||
input logic PWRITE,
|
||||
input logic PENABLE,
|
||||
output logic [P.XLEN-1:0] PRDATA,
|
||||
output logic PREADY,
|
||||
input logic UARTIntr,GPIOIntr,
|
||||
output logic MExtInt, SExtInt
|
||||
output logic PREADY,
|
||||
input logic UARTIntr,GPIOIntr,
|
||||
output logic MExtInt, SExtInt
|
||||
);
|
||||
|
||||
logic memwrite, memread;
|
||||
logic [23:0] entry;
|
||||
logic [31:0] Din, Dout;
|
||||
logic memwrite, memread;
|
||||
logic [23:0] entry;
|
||||
logic [31:0] Din, Dout;
|
||||
|
||||
// context-independent signals
|
||||
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 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 entry = {PADDR[23:2],2'b0};
|
||||
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 entry = {PADDR[23:2],2'b0};
|
||||
|
||||
// account for subword read/write circuitry
|
||||
// -- 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
|
||||
// ==================
|
||||
|
||||
always @(posedge PCLK) begin
|
||||
// resetting
|
||||
if (~PRESETn) begin
|
||||
@ -110,19 +111,19 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
|
||||
casez(entry)
|
||||
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
|
||||
24'h002000: intEn[0][`N:1] <= #1 Din[`N:1];
|
||||
24'h002080: intEn[1][`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];
|
||||
`endif
|
||||
`ifndef PLIC_NUM_SRC_LT_32
|
||||
24'h002000: intEn[0][31:1] <= #1 Din[31:1];
|
||||
24'h002004: intEn[0][`N:32] <= #1 Din[31:0];
|
||||
24'h002080: intEn[1][31:1] <= #1 Din[31:1];
|
||||
24'h002084: intEn[1][`N:32] <= #1 Din[31:0];
|
||||
24'h002000: intEn[0][31:1] <= #1 Din[31:1];
|
||||
24'h002004: intEn[0][`N:32] <= #1 Din[31:0];
|
||||
24'h002080: intEn[1][31:1] <= #1 Din[31:1];
|
||||
24'h002084: intEn[1][`N:32] <= #1 Din[31:0];
|
||||
`endif
|
||||
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'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'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'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
|
||||
endcase
|
||||
// Read synchronously because a read can have side effect of changing intInProgress
|
||||
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 SExtInt = |(threshMask[1] & priorities_with_irqs[1]);
|
||||
endmodule
|
||||
|
||||
|
@ -30,33 +30,33 @@
|
||||
|
||||
module ram_ahb import cvw::*; #(parameter cvw_t P,
|
||||
parameter BASE=0, RANGE = 65535) (
|
||||
input logic HCLK, HRESETn,
|
||||
input logic HSELRam,
|
||||
input logic HCLK, HRESETn,
|
||||
input logic HSELRam,
|
||||
input logic [P.PA_BITS-1:0] HADDR,
|
||||
input logic HWRITE,
|
||||
input logic HREADY,
|
||||
input logic [1:0] HTRANS,
|
||||
input logic HWRITE,
|
||||
input logic HREADY,
|
||||
input logic [1:0] HTRANS,
|
||||
input logic [P.XLEN-1:0] HWDATA,
|
||||
input logic [P.XLEN/8-1:0] HWSTRB,
|
||||
output logic [P.XLEN-1:0] HREADRam,
|
||||
output logic HRESPRam, HREADYRam
|
||||
output logic HRESPRam, HREADYRam
|
||||
);
|
||||
|
||||
localparam ADDR_WIDTH = $clog2(RANGE/8);
|
||||
localparam OFFSET = $clog2(P.XLEN/8);
|
||||
localparam ADDR_WIDTH = $clog2(RANGE/8);
|
||||
localparam OFFSET = $clog2(P.XLEN/8);
|
||||
|
||||
logic [P.XLEN/8-1:0] ByteMask;
|
||||
logic [P.PA_BITS-1:0] HADDRD, RamAddr;
|
||||
logic initTrans;
|
||||
logic memwrite, memwriteD, memread;
|
||||
logic nextHREADYRam;
|
||||
logic DelayReady;
|
||||
logic initTrans;
|
||||
logic memwrite, memwriteD, memread;
|
||||
logic nextHREADYRam;
|
||||
logic DelayReady;
|
||||
|
||||
// a new AHB transactions starts when HTRANS requests a transaction,
|
||||
// the peripheral is selected, and the previous transaction is completing
|
||||
assign initTrans = HREADY & HSELRam & HTRANS[1] ;
|
||||
assign memwrite = initTrans & HWRITE;
|
||||
assign memread = initTrans & ~HWRITE;
|
||||
assign memwrite = initTrans & HWRITE;
|
||||
assign memread = initTrans & ~HWRITE;
|
||||
|
||||
flopenr #(1) memwritereg(HCLK, ~HRESETn, HREADY, memwrite, memwriteD);
|
||||
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),
|
||||
.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
|
||||
if(`RAM_LATENCY > 0) begin
|
||||
logic [7:0] NextCycle, Cycle;
|
||||
@ -89,15 +88,15 @@ module ram_ahb import cvw::*; #(parameter cvw_t P,
|
||||
|
||||
always_ff @(posedge HCLK)
|
||||
if (~HRESETn) CurrState <= #1 READY;
|
||||
else CurrState <= #1 NextState;
|
||||
else CurrState <= #1 NextState;
|
||||
|
||||
always_comb begin
|
||||
case(CurrState)
|
||||
READY: if(initTrans & ~CycleFlag) NextState = DELAY;
|
||||
else NextState = READY;
|
||||
DELAY: if(CycleFlag) NextState = READY;
|
||||
else NextState = DELAY;
|
||||
default: NextState = READY;
|
||||
else NextState = READY;
|
||||
DELAY: if(CycleFlag) NextState = READY;
|
||||
else NextState = DELAY;
|
||||
default: NextState = READY;
|
||||
endcase
|
||||
end
|
||||
|
||||
@ -110,4 +109,3 @@ module ram_ahb import cvw::*; #(parameter cvw_t P,
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
@ -28,24 +28,23 @@
|
||||
|
||||
module rom_ahb import cvw::*; #(parameter cvw_t P,
|
||||
parameter BASE=0, RANGE = 65535) (
|
||||
input logic HCLK, HRESETn,
|
||||
input logic HSELRom,
|
||||
input logic [P.PA_BITS-1:0] HADDR,
|
||||
input logic HREADY,
|
||||
input logic [1:0] HTRANS,
|
||||
output logic [P.XLEN-1:0] HREADRom,
|
||||
output logic HRESPRom, HREADYRom
|
||||
input logic HCLK, HRESETn,
|
||||
input logic HSELRom,
|
||||
input logic [P.PA_BITS-1:0] HADDR,
|
||||
input logic HREADY,
|
||||
input logic [1:0] HTRANS,
|
||||
output logic [P.XLEN-1:0] HREADRom,
|
||||
output logic HRESPRom, HREADYRom
|
||||
);
|
||||
|
||||
localparam ADDR_WIDTH = $clog2(RANGE/8);
|
||||
localparam OFFSET = $clog2(P.XLEN/8);
|
||||
localparam OFFSET = $clog2(P.XLEN/8);
|
||||
|
||||
// Never stalls
|
||||
assign HREADYRom = 1'b1;
|
||||
assign HRESPRom = 0; // OK
|
||||
assign HRESPRom = 0; // OK
|
||||
|
||||
// single-ported ROM
|
||||
rom1p1r #(ADDR_WIDTH, P.XLEN, P.FPGA)
|
||||
memory(.clk(HCLK), .ce(1'b1), .addr(HADDR[ADDR_WIDTH+OFFSET-1:OFFSET]), .dout(HREADRom));
|
||||
endmodule
|
||||
|
||||
|
@ -45,7 +45,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
|
||||
output logic INTR, TXRDYb, RXRDYb, // interrupt and ready lines
|
||||
// Clocks
|
||||
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
|
||||
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
|
||||
@ -71,9 +71,9 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
|
||||
logic DLAB; // Divisor Latch Access Bit (LCR bit 7)
|
||||
|
||||
// Baud and rx/tx timing
|
||||
logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period
|
||||
logic [16+UART_PRESCALE-1:0] baudcount;
|
||||
logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16
|
||||
logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period
|
||||
logic [16+UART_PRESCALE-1:0] baudcount;
|
||||
logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16
|
||||
logic [3:0] rxbitsreceived, txbitssent;
|
||||
statetype rxstate, txstate;
|
||||
|
||||
@ -122,6 +122,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
|
||||
///////////////////////////////////////////
|
||||
// Input synchronization: 2-stage synchronizer
|
||||
///////////////////////////////////////////
|
||||
|
||||
always_ff @(posedge PCLK) begin
|
||||
{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]} :
|
||||
@ -132,6 +133,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
|
||||
///////////////////////////////////////////
|
||||
// Register interface (Table 1, note some are read only and some write only)
|
||||
///////////////////////////////////////////
|
||||
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) begin // Table 3 Reset Configuration
|
||||
IER <= #1 4'b0;
|
||||
@ -162,13 +164,13 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
|
||||
if (~MEMWb & (A == 3'b101))
|
||||
LSR[6:1] <= #1 Din[6:1]; // recommended only for test, see 8.6.3
|
||||
else begin
|
||||
LSR[0] <= #1 rxdataready; // Data ready
|
||||
LSR[1] <= #1 (LSR[1] | RXBR[10]) & ~squashRXerrIP;; // overrun error
|
||||
LSR[2] <= #1 (LSR[2] | RXBR[9]) & ~squashRXerrIP; // parity error
|
||||
LSR[3] <= #1 (LSR[3] | RXBR[8]) & ~squashRXerrIP; // framing error
|
||||
LSR[4] <= #1 (LSR[4] | rxbreak) & ~squashRXerrIP; // break indicator
|
||||
LSR[5] <= #1 THRE; // THRE
|
||||
LSR[6] <= #1 ~txsrfull & THRE; // TEMT
|
||||
LSR[0] <= #1 rxdataready; // Data ready
|
||||
LSR[1] <= #1 (LSR[1] | RXBR[10]) & ~squashRXerrIP;; // overrun error
|
||||
LSR[2] <= #1 (LSR[2] | RXBR[9]) & ~squashRXerrIP; // parity error
|
||||
LSR[3] <= #1 (LSR[3] | RXBR[8]) & ~squashRXerrIP; // framing error
|
||||
LSR[4] <= #1 (LSR[4] | rxbreak) & ~squashRXerrIP; // break indicator
|
||||
LSR[5] <= #1 THRE; // THRE
|
||||
LSR[6] <= #1 ~txsrfull & THRE; // TEMT
|
||||
if (rxfifohaserr) LSR[7] <= #1 1; // any bits in FIFO have error
|
||||
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
|
||||
// the baudcount is not reset to {DLM, DLL, UART_PRESCALE}
|
||||
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) begin
|
||||
baudcount <= #1 1;
|
||||
@ -233,17 +236,18 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
|
||||
///////////////////////////////////////////
|
||||
// receive timing and control
|
||||
///////////////////////////////////////////
|
||||
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) begin
|
||||
rxoversampledcnt <= #1 0;
|
||||
rxstate <= #1 UART_IDLE;
|
||||
rxbitsreceived <= #1 0;
|
||||
rxtimeoutcnt <= #1 0;
|
||||
rxoversampledcnt <= #1 0;
|
||||
rxstate <= #1 UART_IDLE;
|
||||
rxbitsreceived <= #1 0;
|
||||
rxtimeoutcnt <= #1 0;
|
||||
end else begin
|
||||
if (rxstate == UART_IDLE & ~SINsync) begin // got start bit
|
||||
rxstate <= #1 UART_ACTIVE;
|
||||
rxstate <= #1 UART_ACTIVE;
|
||||
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
|
||||
end else if (rxbaudpulse & (rxstate == UART_ACTIVE)) begin
|
||||
rxoversampledcnt <= #1 rxoversampledcnt + 1; // 16x oversampled counter
|
||||
@ -260,13 +264,14 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
|
||||
|
||||
// ***explain why
|
||||
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
|
||||
|
||||
///////////////////////////////////////////
|
||||
// receive shift register, buffer register, FIFO
|
||||
///////////////////////////////////////////
|
||||
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
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
|
||||
@ -282,11 +287,11 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
|
||||
assign rxdata = LCR[3] ? rxdata9[7:0] : rxdata9[8:1]; // discard parity bit
|
||||
|
||||
// ERROR CONDITIONS
|
||||
assign rxparity = ^rxdata;
|
||||
assign rxparityerr = (rxparity ^ rxparitybit ^ ~evenparitysel) & LCR[3]; // Check even/odd parity (*** check if LCR needs to be inverted)
|
||||
assign rxparity = ^rxdata;
|
||||
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 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
|
||||
always_ff @(posedge PCLK)
|
||||
@ -298,7 +303,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
|
||||
end else if (rxstate == UART_DONE) begin
|
||||
RXBR <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; // load recevive buffer register
|
||||
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 (fifoenabled) begin
|
||||
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);
|
||||
end
|
||||
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];
|
||||
/* if (i > 0)
|
||||
assign rxfullbit[i] = ((rxfifohead==i) | rxfullbit[i-1]) & (rxfifotail != i);
|
||||
else
|
||||
assign rxfullbit[0] = ((rxfifohead==i) | rxfullbit[15]) & (rxfifotail != i);*/
|
||||
end
|
||||
assign rxfifohaserr = |(RXerrbit & rxfullbit);
|
||||
assign rxfifohaserr = |(RXerrbit & rxfullbit);
|
||||
|
||||
// receive buffer register and ready bit
|
||||
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;
|
||||
else RXRDYb = rxfifoempty;
|
||||
end else begin
|
||||
RBR = RXBR;
|
||||
RBR = RXBR;
|
||||
RXRDYb = ~rxdataready;
|
||||
end
|
||||
|
||||
///////////////////////////////////////////
|
||||
// transmit timing and control
|
||||
///////////////////////////////////////////
|
||||
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) begin
|
||||
txoversampledcnt <= #1 0;
|
||||
txstate <= #1 UART_IDLE;
|
||||
txbitssent <= #1 0;
|
||||
txstate <= #1 UART_IDLE;
|
||||
txbitssent <= #1 0;
|
||||
end else if ((txstate == UART_IDLE) & txsrfull) begin // start transmitting
|
||||
txstate <= #1 UART_ACTIVE;
|
||||
txstate <= #1 UART_ACTIVE;
|
||||
txoversampledcnt <= #1 1;
|
||||
txbitssent <= #1 0;
|
||||
txbitssent <= #1 0;
|
||||
end else if (txbaudpulse & (txstate == UART_ACTIVE)) begin
|
||||
txoversampledcnt <= #1 txoversampledcnt + 1;
|
||||
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
|
||||
// *** explain; is this necessary?
|
||||
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
|
||||
///////////////////////////////////////////
|
||||
|
||||
always_comb begin // compute value for parity and tx holding register
|
||||
nexttxdata = fifoenabled ? txfifo[txfifotail] : TXHR; // pick from FIFO or holding register
|
||||
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 (fifoenabled) begin
|
||||
txfifo[txfifohead] <= #1 Din;
|
||||
txfifohead <= #1 txfifohead + 1;
|
||||
txfifohead <= #1 txfifohead + 1;
|
||||
end else begin
|
||||
TXHR <= #1 Din;
|
||||
TXHR <= #1 Din;
|
||||
txhrfull <= #1 1;
|
||||
end
|
||||
$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 (fifoenabled) begin
|
||||
if (~txfifoempty & ~txsrfull) begin
|
||||
txsr <= #1 txdata;
|
||||
txsr <= #1 txdata;
|
||||
txfifotail <= #1 txfifotail+1;
|
||||
txsrfull <= #1 1;
|
||||
txsrfull <= #1 1;
|
||||
end
|
||||
end else if (txhrfull) begin
|
||||
txsr <= #1 txdata;
|
||||
txsr <= #1 txdata;
|
||||
txhrfull <= #1 0;
|
||||
txsrfull <= #1 1;
|
||||
end
|
||||
@ -470,13 +477,13 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
|
||||
HeadPointerLastMove <= 1'b0;
|
||||
end
|
||||
|
||||
assign txfifoempty = (txfifohead == txfifotail) & ~HeadPointerLastMove;
|
||||
assign txfifoempty = (txfifohead == txfifotail) & ~HeadPointerLastMove;
|
||||
// verilator lint_off WIDTH
|
||||
assign txfifoentries = (txfifohead >= txfifotail) ? (txfifohead-txfifotail) :
|
||||
(txfifohead + 16 - txfifotail);
|
||||
// verilator lint_on WIDTH
|
||||
//assign txfifofull = (txfifoentries == 4'b1111);
|
||||
assign txfifofull = (txfifohead == txfifotail) & HeadPointerLastMove;
|
||||
//assign txfifofull = (txfifoentries == 4'b1111);
|
||||
assign txfifofull = (txfifohead == txfifotail) & HeadPointerLastMove;
|
||||
|
||||
// transmit buffer ready bit
|
||||
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
|
||||
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
|
||||
///////////////////////////////////////////
|
||||
|
||||
assign RXerr = |LSR[4:1]; // LS interrupt if any of the flags are true
|
||||
assign RXerrIP = RXerr & ~squashRXerrIP; // intr squashed upon reading LSR
|
||||
assign rxdataavailintr = fifoenabled ? rxfifotriggered : rxdataready;
|
||||
@ -533,15 +541,15 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
|
||||
// modem control logic
|
||||
///////////////////////////////////////////
|
||||
|
||||
assign loop = MCR[4];
|
||||
assign loop = MCR[4];
|
||||
assign DTRb = ~MCR[0] | loop; // disable modem signals in loopback mode
|
||||
assign RTSb = ~MCR[1] | loop;
|
||||
assign OUT1b = ~MCR[2] | loop;
|
||||
assign OUT2b = ~MCR[3] | loop;
|
||||
|
||||
assign DLAB = LCR[7];
|
||||
assign evenparitysel = LCR[4];
|
||||
assign fifoenabled = FCR[0];
|
||||
assign evenparitysel = LCR[4];
|
||||
assign fifoenabled = FCR[0];
|
||||
assign fifodmamodesel = FCR[3];
|
||||
always_comb
|
||||
case (FCR[7:6])
|
||||
|
@ -29,18 +29,18 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module uart_apb import cvw::*; #(parameter cvw_t P) (
|
||||
input logic PCLK, PRESETn,
|
||||
input logic PSEL,
|
||||
input logic [2:0] PADDR,
|
||||
input logic [P.XLEN-1:0] PWDATA,
|
||||
input logic PCLK, PRESETn,
|
||||
input logic PSEL,
|
||||
input logic [2:0] PADDR,
|
||||
input logic [P.XLEN-1:0] PWDATA,
|
||||
input logic [P.XLEN/8-1:0] PSTRB,
|
||||
input logic PWRITE,
|
||||
input logic PENABLE,
|
||||
output logic [P.XLEN-1:0] PRDATA,
|
||||
output logic PREADY,
|
||||
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 OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU
|
||||
input logic PWRITE,
|
||||
input logic PENABLE,
|
||||
output logic [P.XLEN-1:0] PRDATA,
|
||||
output logic PREADY,
|
||||
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 OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU
|
||||
|
||||
// UART interface signals
|
||||
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 memread = ~PWRITE & PENABLE & PSEL;
|
||||
assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond
|
||||
assign entry = PADDR[2:0];
|
||||
assign MEMRb = ~memread;
|
||||
assign MEMWb = ~memwrite;
|
||||
assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond
|
||||
assign entry = PADDR[2:0];
|
||||
assign MEMRb = ~memread;
|
||||
assign MEMWb = ~memwrite;
|
||||
|
||||
if (P.XLEN == 64) begin:uart
|
||||
always_comb begin
|
||||
@ -97,4 +97,3 @@ module uart_apb import cvw::*; #(parameter cvw_t P) (
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
@ -29,58 +29,58 @@
|
||||
|
||||
module uncore import cvw::*; #(parameter cvw_t P)(
|
||||
// AHB Bus Interface
|
||||
input logic HCLK, HRESETn,
|
||||
input logic TIMECLK,
|
||||
input logic HCLK, HRESETn,
|
||||
input logic TIMECLK,
|
||||
input logic [P.PA_BITS-1:0] HADDR,
|
||||
input logic [P.AHBW-1:0] HWDATA,
|
||||
input logic [P.XLEN/8-1:0] HWSTRB,
|
||||
input logic HWRITE,
|
||||
input logic [2:0] HSIZE,
|
||||
input logic [2:0] HBURST,
|
||||
input logic [3:0] HPROT,
|
||||
input logic [1:0] HTRANS,
|
||||
input logic HMASTLOCK,
|
||||
input logic HWRITE,
|
||||
input logic [2:0] HSIZE,
|
||||
input logic [2:0] HBURST,
|
||||
input logic [3:0] HPROT,
|
||||
input logic [1:0] HTRANS,
|
||||
input logic HMASTLOCK,
|
||||
input logic [P.AHBW-1:0] HRDATAEXT,
|
||||
input logic HREADYEXT, HRESPEXT,
|
||||
input logic HREADYEXT, HRESPEXT,
|
||||
output logic [P.AHBW-1:0] HRDATA,
|
||||
output logic HREADY, HRESP,
|
||||
output logic HSELEXT,
|
||||
output logic HREADY, HRESP,
|
||||
output logic HSELEXT,
|
||||
// peripheral pins
|
||||
output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT
|
||||
output logic MExtInt, SExtInt, // External interrupts from PLIC
|
||||
output logic [63:0] MTIME_CLINT, // MTIME, from CLINT
|
||||
input logic [31:0] GPIOIN, // GPIO pin input value
|
||||
output logic [31:0] GPIOOUT, GPIOEN, // GPIO pin output value and enable
|
||||
input logic UARTSin, // UART serial input
|
||||
output logic UARTSout, // UART serial output
|
||||
output logic SDCCmdOut, // SD Card command output
|
||||
output logic SDCCmdOE, // SD Card command output enable
|
||||
input logic SDCCmdIn, // SD Card command input
|
||||
input logic [3:0] SDCDatIn, // SD Card data input
|
||||
output logic SDCCLK // SD Card clock
|
||||
output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT
|
||||
output logic MExtInt, SExtInt, // External interrupts from PLIC
|
||||
output logic [63:0] MTIME_CLINT, // MTIME, from CLINT
|
||||
input logic [31:0] GPIOIN, // GPIO pin input value
|
||||
output logic [31:0] GPIOOUT, GPIOEN, // GPIO pin output value and enable
|
||||
input logic UARTSin, // UART serial input
|
||||
output logic UARTSout, // UART serial output
|
||||
output logic SDCCmdOut, // SD Card command output
|
||||
output logic SDCCmdOE, // SD Card command output enable
|
||||
input logic SDCCmdIn, // SD Card command input
|
||||
input logic [3:0] SDCDatIn, // SD Card data input
|
||||
output logic SDCCLK // SD Card clock
|
||||
);
|
||||
|
||||
logic [P.XLEN-1:0] HREADRam, HREADSDC;
|
||||
|
||||
logic [10:0] HSELRegions;
|
||||
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
|
||||
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
|
||||
logic HRESPRam, HRESPSDC;
|
||||
logic HREADYRam, HRESPSDCD;
|
||||
logic [10:0] HSELRegions;
|
||||
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
|
||||
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
|
||||
logic HRESPRam, HRESPSDC;
|
||||
logic HREADYRam, HRESPSDCD;
|
||||
logic [P.XLEN-1:0] HREADBootRom;
|
||||
logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC;
|
||||
logic HSELNoneD;
|
||||
logic UARTIntr,GPIOIntr;
|
||||
logic SDCIntM;
|
||||
logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC;
|
||||
logic HSELNoneD;
|
||||
logic UARTIntr,GPIOIntr;
|
||||
logic SDCIntM;
|
||||
|
||||
logic PCLK, PRESETn, PWRITE, PENABLE;
|
||||
logic [3:0] PSEL, PREADY;
|
||||
logic [31:0] PADDR;
|
||||
logic PCLK, PRESETn, PWRITE, PENABLE;
|
||||
logic [3:0] PSEL, PREADY;
|
||||
logic [31:0] PADDR;
|
||||
logic [P.XLEN-1:0] PWDATA;
|
||||
logic [P.XLEN/8-1:0] PSTRB;
|
||||
logic [3:0][P.XLEN-1:0] PRDATA;
|
||||
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
|
||||
// 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
|
||||
);
|
||||
end else begin : sdc
|
||||
assign SDCCLK = 0;
|
||||
assign SDCCLK = 0;
|
||||
assign SDCCmdOut = 0;
|
||||
assign SDCCmdOE = 0;
|
||||
assign SDCCmdOE = 0;
|
||||
end
|
||||
|
||||
// AHB Read Multiplexer
|
||||
@ -189,4 +189,3 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
||||
HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD, HSELNoneD});
|
||||
flopenr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HREADY, HSELBRIDGE, HSELBRIDGED);
|
||||
endmodule
|
||||
|
||||
|
105
src/wally/cvw.sv
105
src/wally/cvw.sv
@ -68,31 +68,31 @@ typedef struct packed {
|
||||
logic ICACHE_SUPPORTED;
|
||||
|
||||
// TLB configuration. Entries should be a power of 2
|
||||
int ITLB_ENTRIES;
|
||||
int DTLB_ENTRIES;
|
||||
int ITLB_ENTRIES;
|
||||
int DTLB_ENTRIES;
|
||||
|
||||
// Cache configuration. Sizes should be a power of two
|
||||
// typical configuration 4 ways, 4096 ints per way, 256 bit or more lines
|
||||
int DCACHE_NUMWAYS;
|
||||
int DCACHE_WAYSIZEINBYTES;
|
||||
int DCACHE_LINELENINBITS;
|
||||
int ICACHE_NUMWAYS;
|
||||
int ICACHE_WAYSIZEINBYTES;
|
||||
int ICACHE_LINELENINBITS;
|
||||
int DCACHE_NUMWAYS;
|
||||
int DCACHE_WAYSIZEINBYTES;
|
||||
int DCACHE_LINELENINBITS;
|
||||
int ICACHE_NUMWAYS;
|
||||
int ICACHE_WAYSIZEINBYTES;
|
||||
int ICACHE_LINELENINBITS;
|
||||
|
||||
// Integer Divider Configuration
|
||||
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||
int IDIV_BITSPERCYCLE;
|
||||
int IDIV_BITSPERCYCLE;
|
||||
logic IDIV_ON_FPU;
|
||||
|
||||
// Legal number of PMP entries are 0, 16, or 64
|
||||
int PMP_ENTRIES;
|
||||
int PMP_ENTRIES;
|
||||
|
||||
// Address space
|
||||
logic [63:0] RESET_VECTOR;
|
||||
|
||||
// WFI Timeout Wait
|
||||
int WFI_TIMEOUT_BIT;
|
||||
int WFI_TIMEOUT_BIT;
|
||||
|
||||
// Peripheral Addresses
|
||||
// Peripheral memory space extends from BASE to BASE+RANGE
|
||||
@ -134,24 +134,23 @@ typedef struct packed {
|
||||
logic GPIO_LOOPBACK_TEST;
|
||||
|
||||
// Hardware configuration
|
||||
int UART_PRESCALE ;
|
||||
int UART_PRESCALE ;
|
||||
|
||||
// Interrupt configuration
|
||||
int PLIC_NUM_SRC;
|
||||
int PLIC_NUM_SRC;
|
||||
logic PLIC_NUM_SRC_LT_32;
|
||||
int PLIC_GPIO_ID;
|
||||
int PLIC_UART_ID;
|
||||
|
||||
logic BPRED_SUPPORTED;
|
||||
BranchPredictorType BPRED_TYPE;
|
||||
int BPRED_NUM_LHR;
|
||||
int BPRED_SIZE;
|
||||
int BTB_SIZE;
|
||||
int PLIC_GPIO_ID;
|
||||
int PLIC_UART_ID;
|
||||
|
||||
logic BPRED_SUPPORTED;
|
||||
BranchPredictorType BPRED_TYPE;
|
||||
int BPRED_NUM_LHR;
|
||||
int BPRED_SIZE;
|
||||
int BTB_SIZE;
|
||||
|
||||
// FPU division architecture
|
||||
int RADIX;
|
||||
int DIVCOPIES;
|
||||
int RADIX;
|
||||
int DIVCOPIES;
|
||||
|
||||
// bit manipulation
|
||||
logic ZBA_SUPPORTED;
|
||||
@ -204,47 +203,47 @@ typedef struct packed {
|
||||
int PMPCFG_ENTRIES;
|
||||
|
||||
// Floating point constants for Quad, Double, Single, and Half precisions
|
||||
int Q_LEN;
|
||||
int Q_NE;
|
||||
int Q_NF;
|
||||
int Q_BIAS;
|
||||
int Q_LEN;
|
||||
int Q_NE;
|
||||
int Q_NF;
|
||||
int Q_BIAS;
|
||||
logic [1:0] Q_FMT;
|
||||
int D_LEN;
|
||||
int D_NE;
|
||||
int D_NF;
|
||||
int D_BIAS;
|
||||
int D_LEN;
|
||||
int D_NE;
|
||||
int D_NF;
|
||||
int D_BIAS;
|
||||
logic [1:0] D_FMT;
|
||||
int S_LEN;
|
||||
int S_NE;
|
||||
int S_NF;
|
||||
int S_BIAS;
|
||||
int S_LEN;
|
||||
int S_NE;
|
||||
int S_NF;
|
||||
int S_BIAS;
|
||||
logic [1:0] S_FMT;
|
||||
int H_LEN;
|
||||
int H_NE;
|
||||
int H_NF;
|
||||
int H_BIAS;
|
||||
int H_LEN;
|
||||
int H_NE;
|
||||
int H_NF;
|
||||
int H_BIAS;
|
||||
logic [1:0] H_FMT;
|
||||
|
||||
// Floating point length FLEN and number of exponent (NE) and fraction (NF) bits
|
||||
int FLEN;
|
||||
int NE ;
|
||||
int NF ;
|
||||
int NE ;
|
||||
int NF ;
|
||||
logic [1:0] FMT ;
|
||||
int BIAS;
|
||||
int BIAS;
|
||||
|
||||
// Floating point constants needed for FPU paramerterization
|
||||
int FPSIZES;
|
||||
int FMTBITS;
|
||||
int LEN1 ;
|
||||
int NE1 ;
|
||||
int NF1 ;
|
||||
int FPSIZES;
|
||||
int FMTBITS;
|
||||
int LEN1 ;
|
||||
int NE1 ;
|
||||
int NF1 ;
|
||||
logic [1:0] FMT1 ;
|
||||
int BIAS1;
|
||||
int LEN2 ;
|
||||
int NE2 ;
|
||||
int NF2 ;
|
||||
int BIAS1;
|
||||
int LEN2 ;
|
||||
int NE2 ;
|
||||
int NF2 ;
|
||||
logic [1:0] FMT2 ;
|
||||
int BIAS2;
|
||||
int BIAS2;
|
||||
|
||||
// largest length in IEU/FPU
|
||||
int CVTLEN;
|
||||
@ -256,7 +255,7 @@ typedef struct packed {
|
||||
|
||||
// division constants
|
||||
int DIVN ;
|
||||
int LOGR;
|
||||
int LOGR ;
|
||||
int RK ;
|
||||
int LOGRK ;
|
||||
int FPDUR ;
|
||||
|
@ -32,12 +32,12 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
input logic MTimerInt, MExtInt, SExtInt, MSwInt,
|
||||
input logic [63:0] MTIME_CLINT,
|
||||
// Bus Interface
|
||||
input logic [P.AHBW-1:0] HRDATA,
|
||||
input logic [P.AHBW-1:0] HRDATA,
|
||||
input logic HREADY, HRESP,
|
||||
output logic HCLK, HRESETn,
|
||||
output logic [P.PA_BITS-1:0] HADDR,
|
||||
output logic [P.AHBW-1:0] HWDATA,
|
||||
output logic [P.XLEN/8-1:0] HWSTRB,
|
||||
output logic [P.PA_BITS-1:0] HADDR,
|
||||
output logic [P.AHBW-1:0] HWDATA,
|
||||
output logic [P.XLEN/8-1:0] HWSTRB,
|
||||
output logic HWRITE,
|
||||
output logic [2:0] HSIZE,
|
||||
output logic [2:0] HBURST,
|
||||
@ -55,15 +55,15 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
logic IntDivE, W64E;
|
||||
logic CSRReadM, CSRWriteM, PrivilegedM;
|
||||
logic [1:0] AtomicM;
|
||||
logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE;
|
||||
logic [P.XLEN-1:0] SrcAM;
|
||||
logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE;
|
||||
logic [P.XLEN-1:0] SrcAM;
|
||||
logic [2:0] Funct3E;
|
||||
logic [31:0] InstrD;
|
||||
logic [31:0] InstrM, InstrOrigM;
|
||||
logic [P.XLEN-1:0] PCSpillF, PCE, PCLinkE;
|
||||
logic [P.XLEN-1:0] PCM;
|
||||
logic [P.XLEN-1:0] CSRReadValW, MDUResultW;
|
||||
logic [P.XLEN-1:0] UnalignedPCNextF, PC2NextF;
|
||||
logic [P.XLEN-1:0] PCSpillF, PCE, PCLinkE;
|
||||
logic [P.XLEN-1:0] PCM;
|
||||
logic [P.XLEN-1:0] CSRReadValW, MDUResultW;
|
||||
logic [P.XLEN-1:0] UnalignedPCNextF, PC2NextF;
|
||||
logic [1:0] MemRWM;
|
||||
logic InstrValidD, InstrValidE, InstrValidM;
|
||||
logic InstrMisalignedFaultM;
|
||||
@ -83,31 +83,31 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
logic [4:0] RdE, RdM, RdW;
|
||||
logic FPUStallD;
|
||||
logic FWriteIntE;
|
||||
logic [P.FLEN-1:0] FWriteDataM;
|
||||
logic [P.XLEN-1:0] FIntResM;
|
||||
logic [P.XLEN-1:0] FCvtIntResW;
|
||||
logic [P.FLEN-1:0] FWriteDataM;
|
||||
logic [P.XLEN-1:0] FIntResM;
|
||||
logic [P.XLEN-1:0] FCvtIntResW;
|
||||
logic FCvtIntW;
|
||||
logic FDivBusyE;
|
||||
logic FRegWriteM;
|
||||
logic FCvtIntStallD;
|
||||
logic FpLoadStoreM;
|
||||
logic [4:0] SetFflagsM;
|
||||
logic [P.XLEN-1:0] FIntDivResultW;
|
||||
logic [P.XLEN-1:0] FIntDivResultW;
|
||||
|
||||
// memory management unit signals
|
||||
logic ITLBWriteF;
|
||||
logic ITLBMissF;
|
||||
logic [P.XLEN-1:0] SATP_REGW;
|
||||
logic [P.XLEN-1:0] SATP_REGW;
|
||||
logic STATUS_MXR, STATUS_SUM, STATUS_MPRV;
|
||||
logic [1:0] STATUS_MPP, STATUS_FS;
|
||||
logic [1:0] PrivilegeModeW;
|
||||
logic [P.XLEN-1:0] PTE;
|
||||
logic [P.XLEN-1:0] PTE;
|
||||
logic [1:0] PageType;
|
||||
logic sfencevmaM;
|
||||
logic SelHPTW;
|
||||
|
||||
// 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];
|
||||
|
||||
// IMem stalls
|
||||
@ -116,14 +116,14 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// cpu lsu interface
|
||||
logic [2:0] Funct3M;
|
||||
logic [P.XLEN-1:0] IEUAdrE;
|
||||
logic [P.XLEN-1:0] WriteDataM;
|
||||
logic [P.XLEN-1:0] IEUAdrM;
|
||||
logic [P.LLEN-1:0] ReadDataW;
|
||||
logic [P.XLEN-1:0] IEUAdrE;
|
||||
logic [P.XLEN-1:0] WriteDataM;
|
||||
logic [P.XLEN-1:0] IEUAdrM;
|
||||
logic [P.LLEN-1:0] ReadDataW;
|
||||
logic CommittedM;
|
||||
|
||||
// AHB ifu interface
|
||||
logic [P.PA_BITS-1:0] IFUHADDR;
|
||||
logic [P.PA_BITS-1:0] IFUHADDR;
|
||||
logic [2:0] IFUHBURST;
|
||||
logic [1:0] IFUHTRANS;
|
||||
logic [2:0] IFUHSIZE;
|
||||
@ -131,9 +131,9 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
logic IFUHREADY;
|
||||
|
||||
// AHB LSU interface
|
||||
logic [P.PA_BITS-1:0] LSUHADDR;
|
||||
logic [P.XLEN-1:0] LSUHWDATA;
|
||||
logic [P.XLEN/8-1:0] LSUHWSTRB;
|
||||
logic [P.PA_BITS-1:0] LSUHADDR;
|
||||
logic [P.XLEN-1:0] LSUHWDATA;
|
||||
logic [P.XLEN/8-1:0] LSUHWSTRB;
|
||||
logic LSUHWRITE;
|
||||
logic LSUHREADY;
|
||||
|
||||
@ -192,12 +192,12 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
.PCE, .PCLinkE, .FWriteIntE, .FCvtIntE, .IEUAdrE, .IntDivE, .W64E,
|
||||
.Funct3E, .ForwardedSrcAE, .ForwardedSrcBE,
|
||||
// Memory stage interface
|
||||
.SquashSCW, // from LSU
|
||||
.MemRWM, // read/write control goes to LSU
|
||||
.AtomicM, // atomic control goes to LSU
|
||||
.SquashSCW, // from LSU
|
||||
.MemRWM, // read/write control goes to LSU
|
||||
.AtomicM, // atomic control goes to LSU
|
||||
.WriteDataM, // Write data to LSU
|
||||
.Funct3M, // size and signedness to LSU
|
||||
.SrcAM, // to privilege and fpu
|
||||
.Funct3M, // size and signedness to LSU
|
||||
.SrcAM, // to privilege and fpu
|
||||
.RdE, .RdM, .FIntResM, .FlushDCacheM,
|
||||
.BranchD, .BranchE, .JumpD, .JumpE,
|
||||
// Writeback stage
|
||||
@ -219,24 +219,24 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
.LSUHADDR, .HRDATA, .LSUHWDATA, .LSUHWSTRB, .LSUHSIZE,
|
||||
.LSUHBURST, .LSUHTRANS, .LSUHWRITE, .LSUHREADY,
|
||||
// connect to csr or privilege and stay the same.
|
||||
.PrivilegeModeW, .BigEndianM, // connects to csr
|
||||
.PMPCFG_ARRAY_REGW, // connects to csr
|
||||
.PMPADDR_ARRAY_REGW, // connects to csr
|
||||
.PrivilegeModeW, .BigEndianM, // connects to csr
|
||||
.PMPCFG_ARRAY_REGW, // connects to csr
|
||||
.PMPADDR_ARRAY_REGW, // connects to csr
|
||||
// hptw keep i/o
|
||||
.SATP_REGW, // from csr
|
||||
.STATUS_MXR, // from csr
|
||||
.STATUS_SUM, // from csr
|
||||
.STATUS_MPRV, // from csr
|
||||
.STATUS_MPP, // from csr
|
||||
.sfencevmaM, // connects to privilege
|
||||
.DCacheStallM, // connects to privilege
|
||||
.LoadPageFaultM, // connects to privilege
|
||||
.StoreAmoPageFaultM, // connects to privilege
|
||||
.LoadMisalignedFaultM, // connects to privilege
|
||||
.LoadAccessFaultM, // connects to privilege
|
||||
.HPTWInstrAccessFaultF, // connects to privilege
|
||||
.StoreAmoMisalignedFaultM, // connects to privilege
|
||||
.StoreAmoAccessFaultM, // connects to privilege
|
||||
.SATP_REGW, // from csr
|
||||
.STATUS_MXR, // from csr
|
||||
.STATUS_SUM, // from csr
|
||||
.STATUS_MPRV, // from csr
|
||||
.STATUS_MPP, // from csr
|
||||
.sfencevmaM, // connects to privilege
|
||||
.DCacheStallM, // connects to privilege
|
||||
.LoadPageFaultM, // connects to privilege
|
||||
.StoreAmoPageFaultM, // connects to privilege
|
||||
.LoadMisalignedFaultM, // connects to privilege
|
||||
.LoadAccessFaultM, // connects to privilege
|
||||
.HPTWInstrAccessFaultF, // connects to privilege
|
||||
.StoreAmoMisalignedFaultM, // connects to privilege
|
||||
.StoreAmoAccessFaultM, // connects to privilege
|
||||
.InstrUpdateDAF,
|
||||
.PCSpillF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW,
|
||||
.LSUStallM);
|
||||
@ -292,14 +292,14 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||
.FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM);
|
||||
end else begin
|
||||
assign CSRReadValW = 0;
|
||||
assign CSRReadValW = 0;
|
||||
assign UnalignedPCNextF = PC2NextF;
|
||||
assign RetM = 0;
|
||||
assign TrapM = 0;
|
||||
assign wfiM = 0;
|
||||
assign IntPendingM = 0;
|
||||
assign sfencevmaM = 0;
|
||||
assign BigEndianM = 0;
|
||||
assign RetM = 0;
|
||||
assign TrapM = 0;
|
||||
assign wfiM = 0;
|
||||
assign IntPendingM = 0;
|
||||
assign sfencevmaM = 0;
|
||||
assign BigEndianM = 0;
|
||||
end
|
||||
|
||||
// multiply/divide unit
|
||||
@ -310,45 +310,45 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
.MDUResultW, .DivBusyE);
|
||||
end else begin // no M instructions supported
|
||||
assign MDUResultW = 0;
|
||||
assign DivBusyE = 0;
|
||||
assign DivBusyE = 0;
|
||||
end
|
||||
|
||||
// floating point unit
|
||||
if (P.F_SUPPORTED) begin:fpu
|
||||
fpu #(P) fpu(
|
||||
.clk, .reset,
|
||||
.FRM_REGW, // Rounding mode from CSR
|
||||
.InstrD, // instruction from IFU
|
||||
.ReadDataW(ReadDataW[P.FLEN-1:0]),// Read data from memory
|
||||
.ForwardedSrcAE, // Integer input being processed (from IEU)
|
||||
.StallE, .StallM, .StallW, // stall signals from HZU
|
||||
.FlushE, .FlushM, .FlushW, // flush signals from HZU
|
||||
.RdE, .RdM, .RdW, // which FP register to write to (from IEU)
|
||||
.STATUS_FS, // is floating-point enabled?
|
||||
.FRegWriteM, // FP register write enable
|
||||
.FRM_REGW, // Rounding mode from CSR
|
||||
.InstrD, // instruction from IFU
|
||||
.ReadDataW(ReadDataW[P.FLEN-1:0]), // Read data from memory
|
||||
.ForwardedSrcAE, // Integer input being processed (from IEU)
|
||||
.StallE, .StallM, .StallW, // stall signals from HZU
|
||||
.FlushE, .FlushM, .FlushW, // flush signals from HZU
|
||||
.RdE, .RdM, .RdW, // which FP register to write to (from IEU)
|
||||
.STATUS_FS, // is floating-point enabled?
|
||||
.FRegWriteM, // FP register write enable
|
||||
.FpLoadStoreM,
|
||||
.ForwardedSrcBE, // Integer input for intdiv
|
||||
.ForwardedSrcBE, // Integer input for intdiv
|
||||
.Funct3E, .Funct3M, .IntDivE, .W64E, // Integer flags and functions
|
||||
.FPUStallD, // Stall the decode stage
|
||||
.FWriteIntE, .FCvtIntE, // integer register write enable, conversion operation
|
||||
.FWriteDataM, // Data to be written to memory
|
||||
.FIntResM, // data to be written to integer register
|
||||
.FCvtIntResW, // fp -> int conversion result to be stored in int register
|
||||
.FCvtIntW, // fpu result selection
|
||||
.FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage)
|
||||
.IllegalFPUInstrD, // Is the instruction an illegal fpu instruction
|
||||
.SetFflagsM, // FPU flags (to privileged unit)
|
||||
.FPUStallD, // Stall the decode stage
|
||||
.FWriteIntE, .FCvtIntE, // integer register write enable, conversion operation
|
||||
.FWriteDataM, // Data to be written to memory
|
||||
.FIntResM, // data to be written to integer register
|
||||
.FCvtIntResW, // fp -> int conversion result to be stored in int register
|
||||
.FCvtIntW, // fpu result selection
|
||||
.FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage)
|
||||
.IllegalFPUInstrD, // Is the instruction an illegal fpu instruction
|
||||
.SetFflagsM, // FPU flags (to privileged unit)
|
||||
.FIntDivResultW);
|
||||
end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low
|
||||
assign FPUStallD = 0;
|
||||
assign FWriteIntE = 0;
|
||||
assign FCvtIntE = 0;
|
||||
assign FIntResM = 0;
|
||||
assign FCvtIntW = 0;
|
||||
assign FDivBusyE = 0;
|
||||
end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low
|
||||
assign FPUStallD = 0;
|
||||
assign FWriteIntE = 0;
|
||||
assign FCvtIntE = 0;
|
||||
assign FIntResM = 0;
|
||||
assign FCvtIntW = 0;
|
||||
assign FDivBusyE = 0;
|
||||
assign IllegalFPUInstrD = 1;
|
||||
assign SetFflagsM = 0;
|
||||
assign FpLoadStoreM = 0;
|
||||
assign SetFflagsM = 0;
|
||||
assign FpLoadStoreM = 0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -51,9 +51,9 @@ module wallypipelinedsoc import cvw::*; (
|
||||
output logic HREADY,
|
||||
// I/O Interface
|
||||
input logic TIMECLK, // optional for CLINT MTIME counter
|
||||
input logic [31:0] GPIOIN, // inputs from GPIO
|
||||
output logic [31:0] GPIOOUT, // output values for GPIO
|
||||
output logic [31:0] GPIOEN, // output enables for GPIO
|
||||
input logic [31:0] GPIOIN, // inputs from GPIO
|
||||
output logic [31:0] GPIOOUT, // output values for GPIO
|
||||
output logic [31:0] GPIOEN, // output enables for GPIO
|
||||
input logic UARTSin, // UART serial data input
|
||||
output logic UARTSout, // UART serial data output
|
||||
input logic SDCCmdIn, // SDC Command input
|
||||
|
Loading…
Reference in New Issue
Block a user