mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
PLIC and UART passing tests on APB
This commit is contained in:
parent
d73645944f
commit
a599084b88
@ -52,7 +52,7 @@ module clint_apb (
|
|||||||
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; // GPIO never takes >1 cycle to respond
|
assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond
|
||||||
|
|
||||||
// word aligned reads
|
// word aligned reads
|
||||||
if (`XLEN==64) assign #2 entry = {PADDR[15:3], 3'b000};
|
if (`XLEN==64) assign #2 entry = {PADDR[15:3], 3'b000};
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
`define N `PLIC_NUM_SRC
|
`define N `PLIC_NUM_SRC
|
||||||
@ -257,3 +258,4 @@ module plic (
|
|||||||
assign SExtInt = |(threshMask[1] & priorities_with_irqs[1]);
|
assign SExtInt = |(threshMask[1] & priorities_with_irqs[1]);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
*/
|
273
pipelined/src/uncore/plic_apb.sv
Normal file
273
pipelined/src/uncore/plic_apb.sv
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// plic_apb.sv
|
||||||
|
//
|
||||||
|
// Written: bbracker@hmc.edu 18 January 2021
|
||||||
|
// Modified:
|
||||||
|
//
|
||||||
|
// Purpose: Platform-Level Interrupt Controller
|
||||||
|
// Based on RISC-V spec (https://github.com/riscv/riscv-plic-spec/blob/master/riscv-plic.adoc)
|
||||||
|
// With clarifications from ROA's existing implementation (https://roalogic.github.io/plic/docs/AHB-Lite_PLIC_Datasheet.pdf)
|
||||||
|
// Supports only 1 target core and only a global threshold.
|
||||||
|
//
|
||||||
|
// *** Big questions:
|
||||||
|
// Do we detect requests as level-triggered or edge-trigged?
|
||||||
|
// If edge-triggered, do we want to allow 1 source to be able to make a number of repeated requests?
|
||||||
|
//
|
||||||
|
// A component of the Wally configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// MIT LICENSE
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||||
|
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
`define N `PLIC_NUM_SRC
|
||||||
|
// number of interrupt sources
|
||||||
|
// does not include source 0, which does not connect to anything according to spec
|
||||||
|
// up to 63 sources supported; *** in the future, allow up to 1023 sources
|
||||||
|
|
||||||
|
`define C 2
|
||||||
|
// number of conexts
|
||||||
|
// hardcoded to 2 contexts for now; *** later upgrade to arbitrary (up to 15872) contexts
|
||||||
|
|
||||||
|
module plic_apb (
|
||||||
|
input logic PCLK, PRESETn,
|
||||||
|
input logic PSEL,
|
||||||
|
input logic [27:0] PADDR,
|
||||||
|
input logic [`XLEN-1:0] PWDATA,
|
||||||
|
input logic [`XLEN/8-1:0] PSTRB,
|
||||||
|
input logic PWRITE,
|
||||||
|
input logic PENABLE,
|
||||||
|
output logic [`XLEN-1:0] PRDATA,
|
||||||
|
output logic PREADY,
|
||||||
|
/*
|
||||||
|
input logic PCLK, PRESETn,
|
||||||
|
input logic HSELPLIC,
|
||||||
|
input logic [27:0] HADDR, // *** could factor out entry into HADDRd at the level of uncore
|
||||||
|
input logic HWRITE,
|
||||||
|
input logic HREADY,
|
||||||
|
input logic [1:0] HTRANS,
|
||||||
|
input logic [`XLEN-1:0] HWDATA,
|
||||||
|
output logic [`XLEN-1:0] PRDATA,
|
||||||
|
output logic HRESPPLIC, HREADYPLIC, */
|
||||||
|
input logic UARTIntr,GPIOIntr,
|
||||||
|
(* mark_debug = "true" *) output logic MExtInt, SExtInt);
|
||||||
|
|
||||||
|
logic memwrite, memread, initTrans;
|
||||||
|
logic [23:0] entry;
|
||||||
|
logic [31:0] Din, Dout;
|
||||||
|
|
||||||
|
// context-independent signals
|
||||||
|
(* mark_debug = "true" *) logic [`N:1] requests;
|
||||||
|
(* mark_debug = "true" *) logic [`N:1][2:0] intPriority;
|
||||||
|
(* mark_debug = "true" *) logic [`N:1] intInProgress, intPending, nextIntPending;
|
||||||
|
|
||||||
|
// context-dependent signals
|
||||||
|
logic [`C-1:0][2:0] intThreshold;
|
||||||
|
(* mark_debug = "true" *) logic [`C-1:0][`N:1] intEn;
|
||||||
|
logic [`C-1:0][5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
|
||||||
|
(* mark_debug = "true" *) logic [`C-1:0][7:1][`N:1] irqMatrix;
|
||||||
|
logic [`C-1:0][7:1] priorities_with_irqs;
|
||||||
|
logic [`C-1:0][7:1] max_priority_with_irqs;
|
||||||
|
logic [`C-1:0][`N:1] irqs_at_max_priority;
|
||||||
|
logic [`C-1:0][7:1] threshMask;
|
||||||
|
|
||||||
|
// =======
|
||||||
|
// AHB I/O
|
||||||
|
// =======
|
||||||
|
|
||||||
|
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 initTrans = HREADY & HSELPLIC & (HTRANS != 2'b00);
|
||||||
|
assign memread = initTrans & ~HWRITE;
|
||||||
|
// entryd and memwrite are delayed by a cycle because AHB controller waits a cycle before outputting write data
|
||||||
|
flopr #(1) memwriteflop(PCLK, ~HRESETn, initTrans & HWRITE, memwrite);
|
||||||
|
flopr #(24) entrydflop(PCLK, ~PRESETn, entry, entryd);
|
||||||
|
assign HRESPPLIC = 0; // OK
|
||||||
|
assign HREADYPLIC = 1'b1; // PLIC never takes >1 cycle to respond */
|
||||||
|
|
||||||
|
// account for subword read/write circuitry
|
||||||
|
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
|
||||||
|
if (`XLEN == 64) begin
|
||||||
|
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 PRDATA = Dout;
|
||||||
|
assign Din = PWDATA[31:0];
|
||||||
|
end
|
||||||
|
|
||||||
|
// ==================
|
||||||
|
// Register Interface
|
||||||
|
// ==================
|
||||||
|
always @(posedge PCLK,negedge PRESETn) begin
|
||||||
|
// resetting
|
||||||
|
if (~PRESETn) begin
|
||||||
|
intPriority <= #1 {`N{3'b0}};
|
||||||
|
intEn <= #1 {2{`N'b0}};
|
||||||
|
intThreshold <= #1 {2{3'b0}};
|
||||||
|
intInProgress <= #1 `N'b0;
|
||||||
|
// writing
|
||||||
|
end else begin
|
||||||
|
if (memwrite)
|
||||||
|
casez(entry)
|
||||||
|
24'h0000??: intPriority[entry[7:2]] <= #1 Din[2:0];
|
||||||
|
`ifdef PLIC_NUM_SRC_LT_32 // *** 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];
|
||||||
|
`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];
|
||||||
|
`endif
|
||||||
|
24'h200000: intThreshold[0] <= #1 Din[2:0];
|
||||||
|
24'h200004: intInProgress <= #1 intInProgress & ~(`N'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
||||||
|
24'h201000: intThreshold[1] <= #1 Din[2:0];
|
||||||
|
24'h201004: intInProgress <= #1 intInProgress & ~(`N'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)
|
||||||
|
casez(entry)
|
||||||
|
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
|
||||||
|
`ifdef PLIC_NUM_SRC_LT_32
|
||||||
|
24'h001000: Dout <= #1 {{(31-`N){1'b0}},intPending,1'b0};
|
||||||
|
24'h002000: Dout <= #1 {{(31-`N){1'b0}},intEn[0],1'b0};
|
||||||
|
24'h002080: Dout <= #1 {{(31-`N){1'b0}},intEn[1],1'b0};
|
||||||
|
`endif
|
||||||
|
`ifndef PLIC_NUM_SRC_LT_32
|
||||||
|
24'h001000: Dout <= #1 {intPending[31:1],1'b0};
|
||||||
|
24'h001004: Dout <= #1 {{(63-`N){1'b0}},intPending[`N:32]};
|
||||||
|
24'h002000: Dout <= #1 {intEn[0][31:1],1'b0};
|
||||||
|
24'h002004: Dout <= #1 {{(63-`N){1'b0}},intEn[0][`N:32]};
|
||||||
|
24'h002080: Dout <= #1 {intEn[0][31:1],1'b0};
|
||||||
|
24'h002084: Dout <= #1 {{(63-`N){1'b0}},intEn[1][`N:32]};
|
||||||
|
`endif
|
||||||
|
24'h200000: Dout <= #1 {29'b0,intThreshold[0]};
|
||||||
|
24'h200004: begin
|
||||||
|
Dout <= #1 {26'b0,intClaim[0]};
|
||||||
|
intInProgress <= #1 intInProgress | (`N'b1 << (intClaim[0]-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||||
|
end
|
||||||
|
24'h201000: Dout <= #1 {29'b0,intThreshold[1]};
|
||||||
|
24'h201004: begin
|
||||||
|
Dout <= #1 {26'b0,intClaim[1]};
|
||||||
|
intInProgress <= #1 intInProgress | (`N'b1 << (intClaim[1]-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||||
|
end
|
||||||
|
default: Dout <= #1 32'h0; // invalid access
|
||||||
|
endcase
|
||||||
|
else Dout <= #1 32'h0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// connect sources to requests
|
||||||
|
always_comb begin
|
||||||
|
requests = `N'b0;
|
||||||
|
`ifdef PLIC_GPIO_ID
|
||||||
|
requests[`PLIC_GPIO_ID] = GPIOIntr;
|
||||||
|
`endif
|
||||||
|
`ifdef PLIC_UART_ID
|
||||||
|
requests[`PLIC_UART_ID] = UARTIntr;
|
||||||
|
`endif
|
||||||
|
end
|
||||||
|
|
||||||
|
// pending interrupt requests
|
||||||
|
//assign nextIntPending = (intPending | requests) & ~intInProgress; //
|
||||||
|
assign nextIntPending = requests; // DH: RT made this change May 2022, but it seems to be a bug to not consider intInProgress; see May 23, 2022 slack discussion
|
||||||
|
flopr #(`N) intPendingFlop(PCLK,~PRESETn,nextIntPending,intPending);
|
||||||
|
|
||||||
|
// context-dependent signals
|
||||||
|
genvar ctx;
|
||||||
|
for (ctx=0; ctx<`C; ctx++) begin
|
||||||
|
// request matrix
|
||||||
|
// priority level (rows) X source ID (columns)
|
||||||
|
//
|
||||||
|
// irqMatrix[ctx][pri][src] is high if source <src>
|
||||||
|
// has priority level <pri> and has an "active" interrupt request
|
||||||
|
// ("active" meaning it is enabled in context <ctx> and is pending)
|
||||||
|
genvar src, pri;
|
||||||
|
for (pri=1; pri<=7; pri++) begin
|
||||||
|
for (src=1; src<=`N; src++) begin
|
||||||
|
assign irqMatrix[ctx][pri][src] = (intPriority[src]==pri) & intPending[src] & intEn[ctx][src];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// which prority levels have one or more active requests?
|
||||||
|
assign priorities_with_irqs[ctx][7:1] = {
|
||||||
|
|irqMatrix[ctx][7],
|
||||||
|
|irqMatrix[ctx][6],
|
||||||
|
|irqMatrix[ctx][5],
|
||||||
|
|irqMatrix[ctx][4],
|
||||||
|
|irqMatrix[ctx][3],
|
||||||
|
|irqMatrix[ctx][2],
|
||||||
|
|irqMatrix[ctx][1]
|
||||||
|
};
|
||||||
|
|
||||||
|
// get the highest priority level that has active requests
|
||||||
|
assign max_priority_with_irqs[ctx][7:1] = {
|
||||||
|
priorities_with_irqs[ctx][7],
|
||||||
|
priorities_with_irqs[ctx][6] & ~|priorities_with_irqs[ctx][7],
|
||||||
|
priorities_with_irqs[ctx][5] & ~|priorities_with_irqs[ctx][7:6],
|
||||||
|
priorities_with_irqs[ctx][4] & ~|priorities_with_irqs[ctx][7:5],
|
||||||
|
priorities_with_irqs[ctx][3] & ~|priorities_with_irqs[ctx][7:4],
|
||||||
|
priorities_with_irqs[ctx][2] & ~|priorities_with_irqs[ctx][7:3],
|
||||||
|
priorities_with_irqs[ctx][1] & ~|priorities_with_irqs[ctx][7:2]
|
||||||
|
};
|
||||||
|
|
||||||
|
// of the sources at the highest priority level that has active requests,
|
||||||
|
// which sources have active requests?
|
||||||
|
assign irqs_at_max_priority[ctx][`N:1] =
|
||||||
|
({`N{max_priority_with_irqs[ctx][7]}} & irqMatrix[ctx][7]) |
|
||||||
|
({`N{max_priority_with_irqs[ctx][6]}} & irqMatrix[ctx][6]) |
|
||||||
|
({`N{max_priority_with_irqs[ctx][5]}} & irqMatrix[ctx][5]) |
|
||||||
|
({`N{max_priority_with_irqs[ctx][4]}} & irqMatrix[ctx][4]) |
|
||||||
|
({`N{max_priority_with_irqs[ctx][3]}} & irqMatrix[ctx][3]) |
|
||||||
|
({`N{max_priority_with_irqs[ctx][2]}} & irqMatrix[ctx][2]) |
|
||||||
|
({`N{max_priority_with_irqs[ctx][1]}} & irqMatrix[ctx][1]);
|
||||||
|
|
||||||
|
// of the sources at the highest priority level that has active requests,
|
||||||
|
// choose the source with the lowest source ID to be the most urgent
|
||||||
|
// and set intClaim to the source ID of the most urgent active request
|
||||||
|
integer k;
|
||||||
|
always_comb begin
|
||||||
|
intClaim[ctx] = 6'b0;
|
||||||
|
for (k=`N; k>0; k--) begin
|
||||||
|
if (irqs_at_max_priority[ctx][k]) intClaim[ctx] = k[5:0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// create threshold mask
|
||||||
|
always_comb begin
|
||||||
|
threshMask[ctx][7] = (intThreshold[ctx] != 7);
|
||||||
|
threshMask[ctx][6] = (intThreshold[ctx] != 6) & threshMask[ctx][7];
|
||||||
|
threshMask[ctx][5] = (intThreshold[ctx] != 5) & threshMask[ctx][6];
|
||||||
|
threshMask[ctx][4] = (intThreshold[ctx] != 4) & threshMask[ctx][5];
|
||||||
|
threshMask[ctx][3] = (intThreshold[ctx] != 3) & threshMask[ctx][4];
|
||||||
|
threshMask[ctx][2] = (intThreshold[ctx] != 2) & threshMask[ctx][3];
|
||||||
|
threshMask[ctx][1] = (intThreshold[ctx] != 1) & threshMask[ctx][2];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
// is the max priority > threshold?
|
||||||
|
// *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?
|
||||||
|
assign MExtInt = |(threshMask[0] & priorities_with_irqs[0]);
|
||||||
|
assign SExtInt = |(threshMask[1] & priorities_with_irqs[1]);
|
||||||
|
endmodule
|
||||||
|
|
@ -30,6 +30,7 @@
|
|||||||
// OR OTHER DEALINGS IN THE SOFTWARE.
|
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module uart (
|
module uart (
|
||||||
@ -103,3 +104,4 @@ module uart (
|
|||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
*/
|
@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
module uartPC16550D(
|
module uartPC16550D(
|
||||||
// Processor Interface
|
// Processor Interface
|
||||||
input logic HCLK, HRESETn,
|
input logic PCLK, PRESETn,
|
||||||
input logic [2:0] A,
|
input logic [2:0] A,
|
||||||
input logic [7:0] Din,
|
input logic [7:0] Din,
|
||||||
output logic [7:0] Dout,
|
output logic [7:0] Dout,
|
||||||
@ -132,7 +132,7 @@ module uartPC16550D(
|
|||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// Input synchronization: 2-stage synchronizer
|
// Input synchronization: 2-stage synchronizer
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
always_ff @(posedge HCLK) 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]} :
|
||||||
{SINd, DSRbd, DCDbd, CTSbd, RIbd}; // syncrhonized signals, handle loopback testing
|
{SINd, DSRbd, DCDbd, CTSbd, RIbd}; // syncrhonized signals, handle loopback testing
|
||||||
@ -142,8 +142,8 @@ module uartPC16550D(
|
|||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// 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 HCLK, negedge HRESETn)
|
always_ff @(posedge PCLK, negedge PRESETn)
|
||||||
if (~HRESETn) begin // Table 3 Reset Configuration
|
if (~PRESETn) begin // Table 3 Reset Configuration
|
||||||
IER <= #1 4'b0;
|
IER <= #1 4'b0;
|
||||||
FCR <= #1 8'b0;
|
FCR <= #1 8'b0;
|
||||||
if (`QEMU) LCR <= #1 8'b0; else LCR <= #1 8'b11; // fpga only **** BUG
|
if (`QEMU) LCR <= #1 8'b0; else LCR <= #1 8'b11; // fpga only **** BUG
|
||||||
@ -229,8 +229,8 @@ module uartPC16550D(
|
|||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// 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 HCLK, negedge HRESETn)
|
always_ff @(posedge PCLK, negedge PRESETn)
|
||||||
if (~HRESETn) begin
|
if (~PRESETn) begin
|
||||||
baudcount <= #1 1;
|
baudcount <= #1 1;
|
||||||
baudpulse <= #1 0;
|
baudpulse <= #1 0;
|
||||||
end else if (~MEMWb & DLAB & (A == 3'b0 | A == 3'b1)) begin
|
end else if (~MEMWb & DLAB & (A == 3'b0 | A == 3'b1)) begin
|
||||||
@ -254,8 +254,8 @@ module uartPC16550D(
|
|||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// receive timing and control
|
// receive timing and control
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
always_ff @(posedge HCLK, negedge HRESETn)
|
always_ff @(posedge PCLK, negedge PRESETn)
|
||||||
if (~HRESETn) begin
|
if (~PRESETn) begin
|
||||||
rxoversampledcnt <= #1 0;
|
rxoversampledcnt <= #1 0;
|
||||||
rxstate <= #1 UART_IDLE;
|
rxstate <= #1 UART_IDLE;
|
||||||
rxbitsreceived <= #1 0;
|
rxbitsreceived <= #1 0;
|
||||||
@ -288,8 +288,8 @@ module uartPC16550D(
|
|||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// receive shift register, buffer register, FIFO
|
// receive shift register, buffer register, FIFO
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
always_ff @(posedge HCLK, negedge HRESETn)
|
always_ff @(posedge PCLK, negedge PRESETn)
|
||||||
if (~HRESETn) 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
|
||||||
assign rxparitybit = rxshiftreg[1]; // parity, if it exists, in bit 1 when all done
|
assign rxparitybit = rxshiftreg[1]; // parity, if it exists, in bit 1 when all done
|
||||||
assign rxstopbit = rxshiftreg[0];
|
assign rxstopbit = rxshiftreg[0];
|
||||||
@ -310,8 +310,8 @@ module uartPC16550D(
|
|||||||
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 HCLK, negedge HRESETn)
|
always_ff @(posedge PCLK, negedge PRESETn)
|
||||||
if (~HRESETn) begin
|
if (~PRESETn) begin
|
||||||
rxfifohead <= #1 0; rxfifotail <= #1 0; rxdataready <= #1 0; RXBR <= #1 0;
|
rxfifohead <= #1 0; rxfifotail <= #1 0; rxdataready <= #1 0; RXBR <= #1 0;
|
||||||
end else begin
|
end else begin
|
||||||
if (rxstate == UART_DONE) begin
|
if (rxstate == UART_DONE) begin
|
||||||
@ -367,8 +367,8 @@ module uartPC16550D(
|
|||||||
assign rxfifohaserr = |(RXerrbit & rxfullbit);
|
assign rxfifohaserr = |(RXerrbit & rxfullbit);
|
||||||
|
|
||||||
// receive buffer register and ready bit
|
// receive buffer register and ready bit
|
||||||
always_ff @(posedge HCLK, negedge HRESETn) // track rxrdy for DMA mode (FCR3 = FCR0 = 1)
|
always_ff @(posedge PCLK, negedge PRESETn) // track rxrdy for DMA mode (FCR3 = FCR0 = 1)
|
||||||
if (~HRESETn) rxfifodmaready <= #1 0;
|
if (~PRESETn) rxfifodmaready <= #1 0;
|
||||||
else if (rxfifotriggered | rxfifotimeout) rxfifodmaready <= #1 1;
|
else if (rxfifotriggered | rxfifotimeout) rxfifodmaready <= #1 1;
|
||||||
else if (rxfifoempty) rxfifodmaready <= #1 0;
|
else if (rxfifoempty) rxfifodmaready <= #1 0;
|
||||||
|
|
||||||
@ -386,8 +386,8 @@ module uartPC16550D(
|
|||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// transmit timing and control
|
// transmit timing and control
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
always_ff @(posedge HCLK, negedge HRESETn)
|
always_ff @(posedge PCLK, negedge PRESETn)
|
||||||
if (~HRESETn) begin
|
if (~PRESETn) begin
|
||||||
txoversampledcnt <= #1 0;
|
txoversampledcnt <= #1 0;
|
||||||
txstate <= #1 UART_IDLE;
|
txstate <= #1 UART_IDLE;
|
||||||
txbitssent <= #1 0;
|
txbitssent <= #1 0;
|
||||||
@ -435,8 +435,8 @@ module uartPC16550D(
|
|||||||
end
|
end
|
||||||
|
|
||||||
// registers & FIFO
|
// registers & FIFO
|
||||||
always_ff @(posedge HCLK, negedge HRESETn)
|
always_ff @(posedge PCLK, negedge PRESETn)
|
||||||
if (~HRESETn) begin
|
if (~PRESETn) begin
|
||||||
txfifohead <= #1 0; txfifotail <= #1 0; txhrfull <= #1 0; txsrfull <= #1 0; TXHR <= #1 0; txsr <= #1 12'hfff;
|
txfifohead <= #1 0; txfifotail <= #1 0; txhrfull <= #1 0; txsrfull <= #1 0; TXHR <= #1 0; txsr <= #1 12'hfff;
|
||||||
end else begin
|
end else begin
|
||||||
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
|
||||||
@ -477,8 +477,8 @@ module uartPC16550D(
|
|||||||
assign txfifofull = (txfifoentries == 4'b1111);
|
assign txfifofull = (txfifoentries == 4'b1111);
|
||||||
|
|
||||||
// transmit buffer ready bit
|
// transmit buffer ready bit
|
||||||
always_ff @(posedge HCLK, negedge HRESETn) // track txrdy for DMA mode (FCR3 = FCR0 = 1)
|
always_ff @(posedge PCLK, negedge PRESETn) // track txrdy for DMA mode (FCR3 = FCR0 = 1)
|
||||||
if (~HRESETn) txfifodmaready <= #1 0;
|
if (~PRESETn) txfifodmaready <= #1 0;
|
||||||
else if (txfifoempty) txfifodmaready <= #1 1;
|
else if (txfifoempty) txfifodmaready <= #1 1;
|
||||||
else if (txfifofull) txfifodmaready <= #1 0;
|
else if (txfifofull) txfifodmaready <= #1 0;
|
||||||
|
|
||||||
@ -514,18 +514,18 @@ module uartPC16550D(
|
|||||||
intrpending = 0;
|
intrpending = 0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
always @(posedge HCLK) INTR <= #1 intrpending; // prevent glitches on interrupt pin
|
always @(posedge PCLK) INTR <= #1 intrpending; // prevent glitches on interrupt pin
|
||||||
|
|
||||||
// Side effect of reading LSR is lowering overrun, parity, framing, break intr's
|
// Side effect of reading LSR is lowering overrun, parity, framing, break intr's
|
||||||
assign setSquashRXerrIP = ~MEMRb & (A==3'b101);
|
assign setSquashRXerrIP = ~MEMRb & (A==3'b101);
|
||||||
assign resetSquashRXerrIP = (rxstate == UART_DONE);
|
assign resetSquashRXerrIP = (rxstate == UART_DONE);
|
||||||
assign squashRXerrIP = (prevSquashRXerrIP | setSquashRXerrIP) & ~resetSquashRXerrIP;
|
assign squashRXerrIP = (prevSquashRXerrIP | setSquashRXerrIP) & ~resetSquashRXerrIP;
|
||||||
flopr #(1) squashRXerrIPreg(HCLK, ~HRESETn, squashRXerrIP, prevSquashRXerrIP);
|
flopr #(1) squashRXerrIPreg(PCLK, ~PRESETn, squashRXerrIP, prevSquashRXerrIP);
|
||||||
// Side effect of reading IIR is lowering THRE_IP if most significant intr
|
// Side effect of reading IIR is lowering THRE_IP if most significant intr
|
||||||
assign setSquashTHRE_IP = ~MEMRb & (A==3'b010) & (intrID==3'h1); // there's a 1-cycle delay on set squash so that THRE_IP doesn't change during the process of reading IIR (otherwise combinational loop)
|
assign setSquashTHRE_IP = ~MEMRb & (A==3'b010) & (intrID==3'h1); // there's a 1-cycle delay on set squash so that THRE_IP doesn't change during the process of reading IIR (otherwise combinational loop)
|
||||||
assign resetSquashTHRE_IP = ~THRE;
|
assign resetSquashTHRE_IP = ~THRE;
|
||||||
assign squashTHRE_IP = prevSquashTHRE_IP & ~resetSquashTHRE_IP;
|
assign squashTHRE_IP = prevSquashTHRE_IP & ~resetSquashTHRE_IP;
|
||||||
flopr #(1) squashTHRE_IPreg(HCLK, ~HRESETn, squashTHRE_IP | setSquashTHRE_IP, prevSquashTHRE_IP);
|
flopr #(1) squashTHRE_IPreg(PCLK, ~PRESETn, squashTHRE_IP | setSquashTHRE_IP, prevSquashTHRE_IP);
|
||||||
|
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// modem control logic
|
// modem control logic
|
||||||
|
123
pipelined/src/uncore/uart_apb.sv
Normal file
123
pipelined/src/uncore/uart_apb.sv
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// uart_apb.sv
|
||||||
|
//
|
||||||
|
// Written: David_Harris@hmc.edu 21 January 2021
|
||||||
|
// Modified:
|
||||||
|
//
|
||||||
|
// Purpose: Interface to Universial Asynchronous Receiver/ Transmitter with FIFOs
|
||||||
|
// Emulates interface of Texas Instruments PC165550D
|
||||||
|
// Compatible with UART in Imperas Virtio model ***
|
||||||
|
//
|
||||||
|
// A component of the Wally configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// MIT LICENSE
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||||
|
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
module uart_apb (
|
||||||
|
input logic PCLK, PRESETn,
|
||||||
|
input logic PSEL,
|
||||||
|
input logic [2:0] PADDR,
|
||||||
|
input logic [`XLEN-1:0] PWDATA,
|
||||||
|
input logic [`XLEN/8-1:0] PSTRB,
|
||||||
|
input logic PWRITE,
|
||||||
|
input logic PENABLE,
|
||||||
|
output logic [`XLEN-1:0] PRDATA,
|
||||||
|
output logic PREADY,
|
||||||
|
/*
|
||||||
|
input logic HCLK, HRESETn,
|
||||||
|
input logic HSELUART,
|
||||||
|
input logic [2:0] HADDR,
|
||||||
|
input logic HWRITE,
|
||||||
|
input logic [`XLEN-1:0] PWDATA,
|
||||||
|
output logic [`XLEN-1:0] HREADUART,
|
||||||
|
output logic HRESPUART, HREADYUART, */
|
||||||
|
(* mark_debug = "true" *) input logic SIN, DSRb, DCDb, CTSb, RIb, // from E1A driver from RS232 interface
|
||||||
|
(* mark_debug = "true" *) output logic SOUT, RTSb, DTRb, // to E1A driver to RS232 interface
|
||||||
|
(* mark_debug = "true" *) output logic OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU
|
||||||
|
|
||||||
|
// UART interface signals
|
||||||
|
logic [2:0] entry;
|
||||||
|
logic MEMRb, MEMWb, memread, memwrite;
|
||||||
|
logic [7:0] Din, Dout;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// rename processor interface signals to match PC16550D and provide one-byte interface
|
||||||
|
flopr #(1) memreadreg(HCLK, ~HRESETn, (HSELUART & ~HWRITE), memread);
|
||||||
|
flopr #(1) memwritereg(HCLK, ~HRESETn, (HSELUART & HWRITE), memwrite);
|
||||||
|
flopr #(3) haddrreg(HCLK, ~HRESETn, HADDR[2:0], A);
|
||||||
|
assign MEMRb = ~memread;
|
||||||
|
assign MEMWb = ~memwrite;
|
||||||
|
|
||||||
|
assign HRESPUART = 0; // OK
|
||||||
|
assign HREADYUART = 1; // should idle high during address phase and respond high when done; will need to be modified if UART ever needs more than 1 cycle to do something
|
||||||
|
*/
|
||||||
|
if (`XLEN == 64) begin:uart
|
||||||
|
always_comb begin
|
||||||
|
PRDATA = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout};
|
||||||
|
case (entry)
|
||||||
|
3'b000: Din = PWDATA[7:0];
|
||||||
|
3'b001: Din = PWDATA[15:8];
|
||||||
|
3'b010: Din = PWDATA[23:16];
|
||||||
|
3'b011: Din = PWDATA[31:24];
|
||||||
|
3'b100: Din = PWDATA[39:32];
|
||||||
|
3'b101: Din = PWDATA[47:40];
|
||||||
|
3'b110: Din = PWDATA[55:48];
|
||||||
|
3'b111: Din = PWDATA[63:56];
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end else begin:uart // 32-bit
|
||||||
|
always_comb begin
|
||||||
|
PRDATA = {Dout, Dout, Dout, Dout};
|
||||||
|
case (entry[1:0])
|
||||||
|
2'b00: Din = PWDATA[7:0];
|
||||||
|
2'b01: Din = PWDATA[15:8];
|
||||||
|
2'b10: Din = PWDATA[23:16];
|
||||||
|
2'b11: Din = PWDATA[31:24];
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
logic BAUDOUTb; // loop tx clock BAUDOUTb back to rx clock RCLK
|
||||||
|
// *** make sure reads don't occur on UART unless fully selected because they could change state. This applies to all peripherals
|
||||||
|
uartPC16550D u(
|
||||||
|
// Processor Interface
|
||||||
|
.PCLK, .PRESETn,
|
||||||
|
.A(entry), .Din,
|
||||||
|
.Dout,
|
||||||
|
.MEMRb, .MEMWb,
|
||||||
|
.INTR, .TXRDYb, .RXRDYb,
|
||||||
|
// Clocks
|
||||||
|
.BAUDOUTb, .RCLK(BAUDOUTb),
|
||||||
|
// E1A Driver
|
||||||
|
.SIN, .DSRb, .DCDb, .CTSb, .RIb,
|
||||||
|
.SOUT, .RTSb, .DTRb, .OUT1b, .OUT2b
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -84,11 +84,11 @@ module uncore (
|
|||||||
|
|
||||||
logic PCLK, PRESETn, PWRITE, PENABLE;
|
logic PCLK, PRESETn, PWRITE, PENABLE;
|
||||||
// logic PSEL, PREADY;
|
// logic PSEL, PREADY;
|
||||||
logic [1:0] PSEL, PREADY;
|
logic [3:0] PSEL, PREADY;
|
||||||
logic [31:0] PADDR;
|
logic [31:0] PADDR;
|
||||||
logic [`XLEN-1:0] PWDATA;
|
logic [`XLEN-1:0] PWDATA;
|
||||||
logic [`XLEN/8-1:0] PSTRB;
|
logic [`XLEN/8-1:0] PSTRB;
|
||||||
logic [1:0][`XLEN-1:0] PRDATA;
|
logic [3:0][`XLEN-1:0] PRDATA;
|
||||||
// logic [`XLEN-1:0][8:0] PRDATA;
|
// logic [`XLEN-1:0][8:0] PRDATA;
|
||||||
logic [`XLEN-1:0] HREADBRIDGE;
|
logic [`XLEN-1:0] HREADBRIDGE;
|
||||||
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
|
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
|
||||||
@ -107,11 +107,11 @@ module uncore (
|
|||||||
assign {HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[7:0];
|
assign {HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[7:0];
|
||||||
|
|
||||||
// AHB -> APB bridge
|
// AHB -> APB bridge
|
||||||
ahbapbbridge #(2) ahbapbbridge
|
ahbapbbridge #(4) ahbapbbridge
|
||||||
(.HCLK, .HRESETn, .HSEL({HSELCLINT, HSELGPIO}), .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HTRANS, .HREADY,
|
(.HCLK, .HRESETn, .HSEL({HSELUART, HSELPLIC, HSELCLINT, HSELGPIO}), .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HTRANS, .HREADY,
|
||||||
.HRDATA(HREADBRIDGE), .HRESP(HRESPBRIDGE), .HREADYOUT(HREADYBRIDGE),
|
.HRDATA(HREADBRIDGE), .HRESP(HRESPBRIDGE), .HREADYOUT(HREADYBRIDGE),
|
||||||
.PCLK, .PRESETn, .PSEL, .PWRITE, .PENABLE, .PADDR, .PWDATA, .PSTRB, .PREADY, .PRDATA);
|
.PCLK, .PRESETn, .PSEL, .PWRITE, .PENABLE, .PADDR, .PWDATA, .PSTRB, .PREADY, .PRDATA);
|
||||||
assign HSELBRIDGE = HSELGPIO | HSELCLINT; // if any of the bridge signals are selected
|
assign HSELBRIDGE = HSELGPIO | HSELCLINT | HSELPLIC | HSELUART; // if any of the bridge signals are selected
|
||||||
|
|
||||||
// on-chip RAM
|
// on-chip RAM
|
||||||
if (`RAM_SUPPORTED) begin : ram
|
if (`RAM_SUPPORTED) begin : ram
|
||||||
@ -155,12 +155,17 @@ module uncore (
|
|||||||
assign MTimerInt = 0; assign MSwInt = 0;
|
assign MTimerInt = 0; assign MSwInt = 0;
|
||||||
end
|
end
|
||||||
if (`PLIC_SUPPORTED == 1) begin : plic
|
if (`PLIC_SUPPORTED == 1) begin : plic
|
||||||
plic plic(
|
/* plic plic(
|
||||||
.HCLK, .HRESETn,
|
.HCLK, .HRESETn,
|
||||||
.HSELPLIC, .HADDR(HADDR[27:0]),
|
.HSELPLIC, .HADDR(HADDR[27:0]),
|
||||||
.HWRITE, .HREADY, .HTRANS, .HWDATA,
|
.HWRITE, .HREADY, .HTRANS, .HWDATA,
|
||||||
.UARTIntr, .GPIOIntr,
|
.UARTIntr, .GPIOIntr,
|
||||||
.HREADPLIC, .HRESPPLIC, .HREADYPLIC,
|
.HREADPLIC, .HRESPPLIC, .HREADYPLIC,
|
||||||
|
.MExtInt, .SExtInt); */
|
||||||
|
plic_apb plic(
|
||||||
|
.PCLK, .PRESETn, .PSEL(PSEL[2]), .PADDR(PADDR[27:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
||||||
|
.PRDATA(PRDATA[2]), .PREADY(PREADY[2]),
|
||||||
|
.UARTIntr, .GPIOIntr,
|
||||||
.MExtInt, .SExtInt);
|
.MExtInt, .SExtInt);
|
||||||
end else begin : plic
|
end else begin : plic
|
||||||
assign MExtInt = 0;
|
assign MExtInt = 0;
|
||||||
@ -186,7 +191,7 @@ module uncore (
|
|||||||
assign GPIOPinsOut = 0; assign GPIOPinsEn = 0; assign GPIOIntr = 0;
|
assign GPIOPinsOut = 0; assign GPIOPinsEn = 0; assign GPIOIntr = 0;
|
||||||
end
|
end
|
||||||
if (`UART_SUPPORTED == 1) begin : uart
|
if (`UART_SUPPORTED == 1) begin : uart
|
||||||
uart uart(
|
/* uart uart(
|
||||||
.HCLK, .HRESETn,
|
.HCLK, .HRESETn,
|
||||||
.HSELUART,
|
.HSELUART,
|
||||||
.HADDR(HADDR[2:0]),
|
.HADDR(HADDR[2:0]),
|
||||||
@ -194,6 +199,12 @@ module uncore (
|
|||||||
.HREADUART, .HRESPUART, .HREADYUART,
|
.HREADUART, .HRESPUART, .HREADYUART,
|
||||||
.SIN(UARTSin), .DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1), // from E1A driver from RS232 interface
|
.SIN(UARTSin), .DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1), // from E1A driver from RS232 interface
|
||||||
.SOUT(UARTSout), .RTSb(), .DTRb(), // to E1A driver to RS232 interface
|
.SOUT(UARTSout), .RTSb(), .DTRb(), // to E1A driver to RS232 interface
|
||||||
|
.OUT1b(), .OUT2b(), .INTR(UARTIntr), .TXRDYb(), .RXRDYb()); // to CPU */
|
||||||
|
uart_apb uart(
|
||||||
|
.PCLK, .PRESETn, .PSEL(PSEL[3]), .PADDR(PADDR[2:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
||||||
|
.PRDATA(PRDATA[3]), .PREADY(PREADY[3]),
|
||||||
|
.SIN(UARTSin), .DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1), // from E1A driver from RS232 interface
|
||||||
|
.SOUT(UARTSout), .RTSb(), .DTRb(), // to E1A driver to RS232 interface
|
||||||
.OUT1b(), .OUT2b(), .INTR(UARTIntr), .TXRDYb(), .RXRDYb()); // to CPU
|
.OUT1b(), .OUT2b(), .INTR(UARTIntr), .TXRDYb(), .RXRDYb()); // to CPU
|
||||||
end else begin : uart
|
end else begin : uart
|
||||||
assign UARTSout = 0; assign UARTIntr = 0;
|
assign UARTSout = 0; assign UARTIntr = 0;
|
||||||
@ -217,35 +228,35 @@ module uncore (
|
|||||||
assign HRDATA = ({`XLEN{HSELRamD}} & HREADRam) |
|
assign HRDATA = ({`XLEN{HSELRamD}} & HREADRam) |
|
||||||
({`XLEN{HSELEXTD}} & HRDATAEXT) |
|
({`XLEN{HSELEXTD}} & HRDATAEXT) |
|
||||||
// ({`XLEN{HSELCLINTD}} & HREADCLINT) |
|
// ({`XLEN{HSELCLINTD}} & HREADCLINT) |
|
||||||
({`XLEN{HSELPLICD}} & HREADPLIC) |
|
// ({`XLEN{HSELPLICD}} & HREADPLIC) |
|
||||||
// ({`XLEN{HSELGPIOD}} & HREADGPIO) |
|
// ({`XLEN{HSELGPIOD}} & HREADGPIO) |
|
||||||
({`XLEN{HSELBRIDGED}} & HREADBRIDGE) |
|
({`XLEN{HSELBRIDGED}} & HREADBRIDGE) |
|
||||||
({`XLEN{HSELBootRomD}} & HREADBootRom) |
|
({`XLEN{HSELBootRomD}} & HREADBootRom) |
|
||||||
({`XLEN{HSELUARTD}} & HREADUART) |
|
// ({`XLEN{HSELUARTD}} & HREADUART) |
|
||||||
({`XLEN{HSELSDCD}} & HREADSDC);
|
({`XLEN{HSELSDCD}} & HREADSDC);
|
||||||
|
|
||||||
assign HRESP = HSELRamD & HRESPRam |
|
assign HRESP = HSELRamD & HRESPRam |
|
||||||
HSELEXTD & HRESPEXT |
|
HSELEXTD & HRESPEXT |
|
||||||
// HSELCLINTD & HRESPCLINT |
|
// HSELCLINTD & HRESPCLINT |
|
||||||
HSELPLICD & HRESPPLIC |
|
// HSELPLICD & HRESPPLIC |
|
||||||
// HSELGPIOD & HRESPGPIO |
|
// HSELGPIOD & HRESPGPIO |
|
||||||
HSELBRIDGE & HRESPBRIDGE |
|
HSELBRIDGE & HRESPBRIDGE |
|
||||||
HSELBootRomD & HRESPBootRom |
|
HSELBootRomD & HRESPBootRom |
|
||||||
HSELUARTD & HRESPUART |
|
// HSELUARTD & HRESPUART |
|
||||||
HSELSDC & HRESPSDC;
|
HSELSDC & HRESPSDC;
|
||||||
|
|
||||||
assign HREADY = HSELRamD & HREADYRam |
|
assign HREADY = HSELRamD & HREADYRam |
|
||||||
HSELEXTD & HREADYEXT |
|
HSELEXTD & HREADYEXT |
|
||||||
// HSELCLINTD & HREADYCLINT |
|
// HSELCLINTD & HREADYCLINT |
|
||||||
HSELPLICD & HREADYPLIC |
|
// HSELPLICD & HREADYPLIC |
|
||||||
// HSELGPIOD & HREADYGPIO |
|
// HSELGPIOD & HREADYGPIO |
|
||||||
HSELBRIDGED & HREADYBRIDGE |
|
HSELBRIDGED & HREADYBRIDGE |
|
||||||
HSELBootRomD & HREADYBootRom |
|
HSELBootRomD & HREADYBootRom |
|
||||||
HSELUARTD & HREADYUART |
|
// HSELUARTD & HREADYUART |
|
||||||
HSELSDCD & HREADYSDC |
|
HSELSDCD & HREADYSDC |
|
||||||
HSELNoneD; // don't lock up the bus if no region is being accessed
|
HSELNoneD; // don't lock up the bus if no region is being accessed
|
||||||
|
|
||||||
// *** remove HREADYGPIO, others
|
// *** remove HREADYGPIO, others that are now unused
|
||||||
|
|
||||||
// Address Decoder Delay (figure 4-2 in spec)
|
// Address Decoder Delay (figure 4-2 in spec)
|
||||||
flopr #(9) hseldelayreg(HCLK, ~HRESETn, HSELRegions, {HSELNoneD, HSELEXTD, HSELBootRomD, HSELRamD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD});
|
flopr #(9) hseldelayreg(HCLK, ~HRESETn, HSELRegions, {HSELNoneD, HSELEXTD, HSELBootRomD, HSELRamD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD});
|
||||||
|
Loading…
Reference in New Issue
Block a user