mirror of
https://github.com/alangarf/apple-one.git
synced 2024-06-10 13:29:42 +00:00
added reset logic to uart and CPU
This commit is contained in:
parent
f081eb674f
commit
0fc84e0b37
|
@ -113,7 +113,13 @@ module apple1(
|
|||
|
||||
// UART
|
||||
wire [7:0] uart_dout;
|
||||
uart my_uart (
|
||||
uart #(
|
||||
25000000, 115200, 8
|
||||
// FIXME:
|
||||
// If simulated, need to reduce baud rate etc down
|
||||
// else the UARTs don't work.
|
||||
// 100, 10, 2
|
||||
)my_uart (
|
||||
.clk(clk25),
|
||||
.reset(reset),
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
* on the output pads if external memory is required.
|
||||
*/
|
||||
|
||||
`define SIM
|
||||
// FIXME - Need to make this flag reach out to test bench
|
||||
//`define SIM
|
||||
|
||||
module cpu( clk, reset, AB, DI, DO, WE, IRQ, NMI, RDY );
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ module async_transmitter(
|
|||
|
||||
////////////////////////////////
|
||||
wire BitTick;
|
||||
BaudTickGen #(ClkFrequency, Baud) tickgen(.clk(clk), .enable(TxD_busy), .tick(BitTick));
|
||||
BaudTickGen #(ClkFrequency, Baud) tickgen(.clk(clk), .reset(reset), .enable(TxD_busy), .tick(BitTick));
|
||||
|
||||
reg [3:0] TxD_state;
|
||||
reg [7:0] TxD_shift;
|
||||
|
@ -72,6 +72,7 @@ endmodule
|
|||
////////////////////////////////////////////////////////
|
||||
module async_receiver(
|
||||
input clk,
|
||||
input reset,
|
||||
input RxD,
|
||||
output reg RxD_data_ready,
|
||||
output reg [7:0] RxD_data, // data received, valid only (for one clock cycle) when RxD_data_ready is asserted
|
||||
|
@ -94,24 +95,38 @@ module async_receiver(
|
|||
reg [3:0] RxD_state;
|
||||
|
||||
wire OversamplingTick;
|
||||
BaudTickGen #(ClkFrequency, Baud, Oversampling) tickgen(.clk(clk), .enable(1'b1), .tick(OversamplingTick));
|
||||
BaudTickGen #(ClkFrequency, Baud, Oversampling) tickgen(.clk(clk), .reset(reset), .enable(1'b1), .tick(OversamplingTick));
|
||||
|
||||
// synchronize RxD to our clk domain
|
||||
reg [1:0] RxD_sync; // 2'b11
|
||||
always @(posedge clk) if(OversamplingTick) RxD_sync <= {RxD_sync[0], RxD};
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset)
|
||||
RxD_sync <= 2'b11;
|
||||
else
|
||||
if(OversamplingTick) RxD_sync <= {RxD_sync[0], RxD};
|
||||
end
|
||||
|
||||
// and filter it
|
||||
reg [1:0] Filter_cnt; // 2'b11
|
||||
reg RxD_bit; // 1'b1
|
||||
always @(posedge clk)
|
||||
if(OversamplingTick)
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset)
|
||||
begin
|
||||
if(RxD_sync[1]==1'b1 && Filter_cnt!=2'b11) Filter_cnt <= Filter_cnt + 1'd1;
|
||||
else if(RxD_sync[1]==1'b0 && Filter_cnt!=2'b00) Filter_cnt <= Filter_cnt - 1'd1;
|
||||
|
||||
if(Filter_cnt==2'b11) RxD_bit <= 1'b1;
|
||||
else if(Filter_cnt==2'b00) RxD_bit <= 1'b0;
|
||||
Filter_cnt <= 2'b11;
|
||||
RxD_bit <= 1'b1;
|
||||
end
|
||||
else
|
||||
if(OversamplingTick)
|
||||
begin
|
||||
if(RxD_sync[1]==1'b1 && Filter_cnt!=2'b11) Filter_cnt <= Filter_cnt + 1'd1;
|
||||
else if(RxD_sync[1]==1'b0 && Filter_cnt!=2'b00) Filter_cnt <= Filter_cnt - 1'd1;
|
||||
|
||||
if(Filter_cnt==2'b11) RxD_bit <= 1'b1;
|
||||
else if(Filter_cnt==2'b00) RxD_bit <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// and decide when is the good time to sample the RxD line
|
||||
function integer log2(input integer v);
|
||||
|
@ -131,30 +146,51 @@ module async_receiver(
|
|||
wire sampleNow = OversamplingTick && (OversamplingCnt==Oversampling/2-1);
|
||||
|
||||
// now we can accumulate the RxD bits in a shift-register
|
||||
always @(posedge clk)
|
||||
case(RxD_state)
|
||||
4'b0000: if(~RxD_bit) RxD_state <= 4'b0001; // start bit found?
|
||||
4'b0001: if(sampleNow) RxD_state <= 4'b1000; // sync start bit to sampleNow
|
||||
4'b1000: if(sampleNow) RxD_state <= 4'b1001; // bit 0
|
||||
4'b1001: if(sampleNow) RxD_state <= 4'b1010; // bit 1
|
||||
4'b1010: if(sampleNow) RxD_state <= 4'b1011; // bit 2
|
||||
4'b1011: if(sampleNow) RxD_state <= 4'b1100; // bit 3
|
||||
4'b1100: if(sampleNow) RxD_state <= 4'b1101; // bit 4
|
||||
4'b1101: if(sampleNow) RxD_state <= 4'b1110; // bit 5
|
||||
4'b1110: if(sampleNow) RxD_state <= 4'b1111; // bit 6
|
||||
4'b1111: if(sampleNow) RxD_state <= 4'b0010; // bit 7
|
||||
4'b0010: if(sampleNow) RxD_state <= 4'b0000; // stop bit
|
||||
default: RxD_state <= 4'b0000;
|
||||
endcase
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset)
|
||||
RxD_state <= 0;
|
||||
else
|
||||
case(RxD_state)
|
||||
4'b0000: if(~RxD_bit) RxD_state <= 4'b0001; // start bit found?
|
||||
4'b0001: if(sampleNow) RxD_state <= 4'b1000; // sync start bit to sampleNow
|
||||
4'b1000: if(sampleNow) RxD_state <= 4'b1001; // bit 0
|
||||
4'b1001: if(sampleNow) RxD_state <= 4'b1010; // bit 1
|
||||
4'b1010: if(sampleNow) RxD_state <= 4'b1011; // bit 2
|
||||
4'b1011: if(sampleNow) RxD_state <= 4'b1100; // bit 3
|
||||
4'b1100: if(sampleNow) RxD_state <= 4'b1101; // bit 4
|
||||
4'b1101: if(sampleNow) RxD_state <= 4'b1110; // bit 5
|
||||
4'b1110: if(sampleNow) RxD_state <= 4'b1111; // bit 6
|
||||
4'b1111: if(sampleNow) RxD_state <= 4'b0010; // bit 7
|
||||
4'b0010: if(sampleNow) RxD_state <= 4'b0000; // stop bit
|
||||
default: RxD_state <= 4'b0000;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
if (sampleNow && RxD_state[3]) RxD_data <= {RxD_bit, RxD_data[7:1]};
|
||||
always @(posedge clk)
|
||||
RxD_data_ready <= (sampleNow && RxD_state==4'b0010 && RxD_bit); // make sure a stop bit is received
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset)
|
||||
RxD_data <= 0;
|
||||
else
|
||||
if (sampleNow && RxD_state[3]) RxD_data <= {RxD_bit, RxD_data[7:1]};
|
||||
end
|
||||
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset)
|
||||
RxD_data_ready <= 0;
|
||||
else
|
||||
RxD_data_ready <= (sampleNow && RxD_state==4'b0010 && RxD_bit); // make sure a stop bit is received
|
||||
end
|
||||
|
||||
reg [l2o+1:0] GapCnt;
|
||||
always @(posedge clk)
|
||||
if (RxD_state!=0) GapCnt<=0; else if(OversamplingTick & ~GapCnt[log2(Oversampling)+1]) GapCnt <= GapCnt + 1'h1;
|
||||
always @(posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset)
|
||||
GapCnt <= 0;
|
||||
else
|
||||
if (RxD_state!=0) GapCnt<=0; else if(OversamplingTick & ~GapCnt[log2(Oversampling)+1]) GapCnt <= GapCnt + 1'h1;
|
||||
end
|
||||
|
||||
assign RxD_idle = GapCnt[l2o+1];
|
||||
always @(posedge clk)
|
||||
|
@ -164,7 +200,7 @@ endmodule
|
|||
|
||||
////////////////////////////////////////////////////////
|
||||
module BaudTickGen(
|
||||
input clk, enable,
|
||||
input clk, reset, enable,
|
||||
output tick // generate a tick at the specified baud rate * oversampling
|
||||
);
|
||||
|
||||
|
@ -179,7 +215,13 @@ module BaudTickGen(
|
|||
localparam ShiftLimiter = log2(Baud*Oversampling >> (31-AccWidth)); // this makes sure Inc calculation doesn't overflow
|
||||
localparam Inc = ((Baud*Oversampling << (AccWidth-ShiftLimiter))+(ClkFrequency>>(ShiftLimiter+1)))/(ClkFrequency>>ShiftLimiter);
|
||||
|
||||
always @(posedge clk) if(enable) Acc <= Acc[AccWidth-1:0] + Inc[AccWidth:0]; else Acc <= Inc[AccWidth:0];
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (reset)
|
||||
Acc <= 0;
|
||||
else
|
||||
if(enable) Acc <= Acc[AccWidth-1:0] + Inc[AccWidth:0]; else Acc <= Inc[AccWidth:0];
|
||||
end
|
||||
assign tick = Acc[AccWidth];
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -43,6 +43,7 @@ module uart(
|
|||
|
||||
async_receiver #(ClkFrequency, Baud, Oversampling) my_rx(
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.RxD(uart_rx),
|
||||
.RxD_data_ready(uart_rx_stb),
|
||||
.RxD_data(rx_data),
|
||||
|
@ -96,49 +97,44 @@ module uart(
|
|||
uart_tx_stb <= 0;
|
||||
uart_rx_ack <= 0;
|
||||
|
||||
if (enable)
|
||||
case (address)
|
||||
|
||||
UART_TX:
|
||||
begin
|
||||
case (address)
|
||||
// UART TX - 0xD012
|
||||
dout <= {uart_tx_status, 7'd0};
|
||||
|
||||
UART_TX:
|
||||
if (w_en)
|
||||
begin
|
||||
// UART TX - 0xD012
|
||||
dout <= {uart_tx_status, 7'd0};
|
||||
|
||||
if (w_en)
|
||||
// Apple 1 terminal only uses 7 bits, MSB indicates
|
||||
// terminal has ack'd RX
|
||||
if (~uart_tx_status && uart_tx_init)
|
||||
begin
|
||||
// Apple 1 terminal only uses 7 bits, MSB indicates
|
||||
// terminal has ack'd RX
|
||||
if (~uart_tx_status && uart_tx_init)
|
||||
begin
|
||||
uart_tx_byte <= {1'b0, din[6:0]};
|
||||
uart_tx_stb <= 1;
|
||||
end
|
||||
else
|
||||
uart_tx_init <= 1;
|
||||
uart_tx_byte <= {1'b0, din[6:0]};
|
||||
uart_tx_stb <= 1;
|
||||
end
|
||||
else
|
||||
uart_tx_init <= 1;
|
||||
end
|
||||
|
||||
UART_RXCR:
|
||||
begin
|
||||
// UART RX CR - 0xD011
|
||||
dout <= {uart_rx_status, 7'b0};
|
||||
end
|
||||
|
||||
UART_RX:
|
||||
begin
|
||||
// UART RX - 0xD010
|
||||
dout <= {uart_rx_status, uart_rx_byte[6:0]};
|
||||
if (~w_en)
|
||||
uart_rx_ack <= 1'b1;
|
||||
end
|
||||
|
||||
default:
|
||||
dout <= 8'b0;
|
||||
endcase
|
||||
end
|
||||
else
|
||||
dout <= 8'b0;
|
||||
|
||||
UART_RXCR:
|
||||
begin
|
||||
// UART RX CR - 0xD011
|
||||
dout <= {uart_rx_status, 7'b0};
|
||||
end
|
||||
|
||||
UART_RX:
|
||||
begin
|
||||
// UART RX - 0xD010
|
||||
dout <= {uart_rx_status, uart_rx_byte[6:0]};
|
||||
if (~w_en && ~uart_rx_ack && enable)
|
||||
uart_rx_ack <= 1'b1;
|
||||
end
|
||||
|
||||
default:
|
||||
dout <= 8'b0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
Loading…
Reference in New Issue
Block a user