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 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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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])
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
105
src/wally/cvw.sv
105
src/wally/cvw.sv
@ -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 ;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user