Fixed minor issues in ALU.v
Rewrote RAM.v RAM should now support read and write RAM CKE will be pulled low when no queries to it are being made Added bank-independent read/write systems Added parameterized per-bank clock-hogging
This commit is contained in:
parent
7ebac10ffc
commit
a3f7a48276
34
ALU.v
34
ALU.v
@ -31,9 +31,9 @@ reg shift_rotate;
|
||||
|
||||
wire [BITS:0] add_out;
|
||||
wire [BITS-1:0] lshift [0:LOG2_BITS];
|
||||
wire [LOG2_BITS:0] lshift_overflow;
|
||||
wire [LOG2_BITS-1:0] lshift_overflow;
|
||||
wire [BITS-1:0] rshift [0:LOG2_BITS];
|
||||
wire [LOG2_BITS:0] rshift_underflow;
|
||||
wire [LOG2_BITS-1:0] rshift_underflow;
|
||||
|
||||
assign z = i_z[7:0];
|
||||
assign o_flags = i_flg;
|
||||
@ -42,33 +42,13 @@ FastAdder8 fa8(.cin(), .a(a), .b(b), .out(add_out[BITS-1:0]), .cout(add_out[BITS
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for(i = 1; i<LOG2_BITS; i = i + 1) begin : shifters
|
||||
LeftBitShifter #(.bits(BITS), .shiftby(2**(i-1))) lsh(i==1 ? a : lshift[i-1], b[i], shift_rotate, lshift[i], lshift_overflow[i]);
|
||||
RightBitShifter #(.bits(BITS), .shiftby(2**(i-1))) rsh(i==1 ? a : rshift[i-1], b[i], shift_rotate, rshift[i], rshift_underflow[i]);
|
||||
for(i = 0; i<LOG2_BITS; i = i + 1) begin : shifters
|
||||
LeftBitShifter #(.bits(BITS), .shiftby(2**i)) lsh(i==0 ? a : lshift[i-1], b[i], shift_rotate, lshift[i], lshift_overflow[i]);
|
||||
RightBitShifter #(.bits(BITS), .shiftby(2**i)) rsh(i==0 ? a : rshift[i-1], b[i], shift_rotate, rshift[i], rshift_underflow[i]);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
integer j;
|
||||
|
||||
// Left shift decoder
|
||||
//LeftBitShifter #(.bits(BITS), .shiftby(1)) (a, b[0], shift_rotate, lshift[0], lshift_overflow[0]);
|
||||
//LeftBitShifter #(.bits(BITS), .shiftby(2)) (lshift[0], b[1], shift_rotate, lshift[1], lshift_overflow[1]);
|
||||
//LeftBitShifter #(.bits(BITS), .shiftby(4)) (lshift[1], b[2], shift_rotate, lshift[2], lshift_overflow[2]);
|
||||
//LeftBitShifter #(.bits(8), .shiftby(8)) (lshift[2], b[3], lshift[3], lshift_overflow[3]);
|
||||
//LeftBitShifter #(.bits(8), .shiftby(16)) (lshift[3], b[4], lshift[4], lshift_overflow[4]);
|
||||
//LeftBitShifter #(.bits(8), .shiftby(32)) (lshift[4], b[5], lshift[5], lshift_overflow[5]);
|
||||
//LeftBitShifter #(.bits(8), .shiftby(64)) (lshift[5], b[6], lshift[6], lshift_overflow[6]);
|
||||
//LeftBitShifter #(.bits(8), .shiftby(128)) (lshift[6], b[7], lshift[7], lshift_overflow[7]);
|
||||
|
||||
// Right shift decoder
|
||||
//RightBitShifter #(.bits(BITS), .shiftby(1)) (a, b[0], shift_rotate, rshift[0], rshift_underflow[0]);
|
||||
//RightBitShifter #(.bits(BITS), .shiftby(2)) (rshift[0], b[1], shift_rotate, rshift[1], rshift_underflow[1]);
|
||||
//RightBitShifter #(.bits(BITS), .shiftby(4)) (rshift[1], b[2], shift_rotate, rshift[2], rshift_underflow[2]);
|
||||
//RightBitShifter #(.bits(8), .shiftby(8)) (rshift[2], b[3], rshift[3], rshift_underflow[3]);
|
||||
//RightBitShifter #(.bits(8), .shiftby(16)) (rshift[3], b[4], rshift[4], rshift_underflow[4]);
|
||||
//RightBitShifter #(.bits(8), .shiftby(32)) (rshift[4], b[5], rshift[5], rshift_underflow[5]);
|
||||
//RightBitShifter #(.bits(8), .shiftby(64)) (rshift[5], b[6], rshift[6], rshift_underflow[6]);
|
||||
//RightBitShifter #(.bits(8), .shiftby(128)) (rshift[6], b[7], rshift[7], rshift_underflow[7]);
|
||||
integer j, k;
|
||||
|
||||
always @* begin
|
||||
case(op & 8'b00011111) // 5-bit instructions: 3 flag bits
|
||||
@ -163,7 +143,7 @@ always @* begin
|
||||
i_z <= ~(a ^ b);
|
||||
i_flg <= 8'b0;
|
||||
end
|
||||
|
||||
|
||||
// CL_MUL
|
||||
/*
|
||||
12: begin
|
||||
|
@ -8,9 +8,9 @@ module Callback(
|
||||
parameter ISIZE;
|
||||
|
||||
reg [ISIZE-1:0] counter;
|
||||
reg [2:0] ctr_trigger = 2'b10;
|
||||
reg [2:0] ctr_trigger = 2'b00;
|
||||
|
||||
assign callback = !counter & ctr_trigger;
|
||||
assign callback = !counter && ctr_trigger ? 1'b1 : 1'b0;
|
||||
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if(reset) begin
|
||||
|
227
RAM.v
227
RAM.v
@ -1,69 +1,188 @@
|
||||
/*
|
||||
* DEVICE INFORMATION:
|
||||
* HY57V641620FTP-7:
|
||||
* RAS latency: 2 or 3 cycles
|
||||
* RCD latency: 2 or 3 cycles
|
||||
* full address_select available for row selection
|
||||
* address_select[7:0] available for col selection
|
||||
*/
|
||||
|
||||
module RAM(
|
||||
input wire clk,
|
||||
output wire [10:0] RAM_addr, // RAM address buffer
|
||||
output wire RAM_A10, // RAM address/auto-precharge
|
||||
output wire [1:0] RAM_bank_sel, // RAM bank selection
|
||||
inout wire [15:0] RAM_data, // RAM data bus
|
||||
output wire RAM_clk, // RAM clock signal
|
||||
output wire RAM_clk_enable, // RAM enable clock
|
||||
output wire RAM_enable, // RAM chip enable
|
||||
output wire RAM_strobe_row, // RAM row strobe
|
||||
output wire RAM_strobe_col, // RAM column strobe
|
||||
output wire RAM_write_enable, // RAM data bus write enable
|
||||
input wire read_rq, // Read request (Internal)
|
||||
input wire write_rq, // Write request (Internal)
|
||||
input wire [1:0] access_bank, // Which bank to access
|
||||
output reg [15:0] RAM_state, // State information (Internal)
|
||||
output wire [3:0] op_trigger // Event trigger wire (per bank)
|
||||
input wire clk, // Clock signal
|
||||
output reg [10:0] RAM_addr, // RAM address buffer
|
||||
output reg RAM_A10, // RAM address/auto-precharge
|
||||
output reg [1:0] RAM_bank_sel, // RAM bank selection
|
||||
inout wire [15:0] RAM_data, // RAM data bus
|
||||
output wire RAM_clk, // RAM clock signal
|
||||
output wire RAM_clk_enable, // RAM enable clock
|
||||
output reg RAM_enable, // RAM chip enable
|
||||
output reg RAM_strobe_row, // RAM row strobe
|
||||
output reg RAM_strobe_col, // RAM column strobe
|
||||
output reg RAM_write_enable, // RAM data bus write enable
|
||||
input wire read_rq, // Read request (Internal)
|
||||
input wire write_rq, // Write request (Internal)
|
||||
input wire [1:0] access_bank, // Which bank to access
|
||||
output wire op_trigger, // Event trigger wire
|
||||
input wire [11:0] address_select, // Address selection when accessing RAM,
|
||||
input wire stop_access, // Close a row
|
||||
output reg [1:0] op_bank // Bank being accessed when op_trigger is pulled high
|
||||
);
|
||||
|
||||
reg [2:0] read_init[0:3]; // Whether or not a read operation has been initiated
|
||||
reg trigger_low; // If trigger should be pulled low on next clock cycle
|
||||
parameter CPB = 4; // Specifies in bit length how many cycles a bank burst can allocate for itself before other banks are checked
|
||||
parameter tRCD = 3 + 1; // Assume RCD latency of 3 cycles
|
||||
parameter tRAS = 3 + 1; // Assume CAS latency of 3 cycles
|
||||
|
||||
genvar k;
|
||||
reg [CPB-1:0] acc_cycles; // Cycles used on current bank
|
||||
reg [1:0] acc_bank; // Which bank is allocating read cycles
|
||||
reg [1:0] acc_close[0:3]; // Requests a close of the current row
|
||||
reg [3:0] acc_type; // The current access type of the bank (0: READ, 1: WRITE)
|
||||
reg [3:0] acc_state [0:3]; // Current access state for each bank (0: READY, 1: OPENING, 2: tRCD, 3: READ, 4: STOPPING)
|
||||
reg [3:0] acc_init_callback; // Pull this high to initiate a callback
|
||||
reg [1:0] event_trigger; // Event triggers drive op_trigger
|
||||
|
||||
wire [3:0] acc_event; // Event update callback wire
|
||||
wire [2:0] callback_timeout[0:3]; // Callback clock cycle definition
|
||||
|
||||
Callback #(.ISIZE(3)) cb0(clk, callback_timeout[0], acc_init_callback[0], acc_event[0]);
|
||||
Callback #(.ISIZE(3)) cb1(clk, callback_timeout[1], acc_init_callback[1], acc_event[1]);
|
||||
Callback #(.ISIZE(3)) cb2(clk, callback_timeout[2], acc_init_callback[2], acc_event[2]);
|
||||
Callback #(.ISIZE(3)) cb3(clk, callback_timeout[3], acc_init_callback[3], acc_event[3]);
|
||||
|
||||
|
||||
// Initialize the ram in an inactive state
|
||||
initial RAM_enable = 1'b1;
|
||||
initial RAM_strobe_row = 1'b1;
|
||||
initial RAM_strobe_col = 1'b1;
|
||||
initial RAM_write_enable = 1'b1;
|
||||
initial acc_bank = 1'b1;
|
||||
|
||||
assign op_trigger = event_trigger[0] ^ event_trigger[1];
|
||||
assign RAM_clk = clk;
|
||||
assign RAM_clk_enable = (acc_state[0] | acc_state[1] | acc_state[2] | acc_state[3]) ? 1'b1 : 1'b0;
|
||||
|
||||
genvar n;
|
||||
generate
|
||||
for(k = 0; k<4; k = k + 1) begin : trigger_gen
|
||||
assign op_trigger[k] = read_init[k] == 3'b011;
|
||||
end
|
||||
for(n = 0; n < 4; n = n + 1) begin : gen_callback_timing
|
||||
assign callback_timeout[n] = acc_state[n][1] ? tRAS : tRCD;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign RAM_enable = read_init[0] == 3'b000 && read_init[1] == 3'b000 && read_init[2] == 3'b000 && read_init[3] == 3'b000;
|
||||
assign RAM_clk_enable = read_init[0] != 3'b000 && read_init[1] != 3'b000 && read_init[2] != 3'b000 && read_init[3] != 3'b000;
|
||||
|
||||
assign RAM_clk = clk; // RAM clock tracks processor input clock
|
||||
|
||||
integer i;
|
||||
|
||||
always @(posedge clk or posedge read_rq) begin
|
||||
if(read_rq) begin
|
||||
if(!read_init[access_bank] && !write_rq) begin
|
||||
read_init[access_bank] <= 3'b001;
|
||||
end
|
||||
always @(posedge read_rq or posedge write_rq or posedge acc_event or posedge stop_access or posedge clk) begin
|
||||
if(read_rq || write_rq) begin
|
||||
if(acc_state[access_bank] == 4'b0000) begin
|
||||
RAM_enable <= 1'b0;
|
||||
RAM_strobe_row <= 1'b0;
|
||||
RAM_strobe_col <= 1'b1;
|
||||
RAM_write_enable <= 1'b1;
|
||||
|
||||
RAM_bank_sel <= access_bank;
|
||||
RAM_addr <= {address_select[11], address_select[9:0]};
|
||||
RAM_A10 <= address_select[10];
|
||||
acc_type[access_bank] <= read_rq ? 1'b0 : 1'b1;
|
||||
acc_state[access_bank] <= 4'b0001;
|
||||
acc_init_callback[access_bank] <= 1'b1;
|
||||
acc_close[access_bank] <= 1'b0;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
if(read_init[0]) begin
|
||||
read_init[0] <= read_init[0] + 3'b001; // Increment read
|
||||
RAM_state[3:0] <= 4'b0001; // STATE: read
|
||||
end
|
||||
if(read_init[1]) begin
|
||||
read_init[1] <= read_init[1] + 3'b001; // Increment read
|
||||
RAM_state[7:4] <= 4'b0001; // STATE: read
|
||||
end
|
||||
if(read_init[2]) begin
|
||||
read_init[2] <= read_init[2] + 3'b001; // Increment read
|
||||
RAM_state[11:8] <= 4'b0001; // STATE: read
|
||||
end
|
||||
if(read_init[3]) begin
|
||||
read_init[3] <= read_init[3] + 3'b001; // Increment read
|
||||
RAM_state[15:12] <= 4'b0001; // STATE: read
|
||||
end
|
||||
else if(stop_access) begin
|
||||
if(acc_state[access_bank])
|
||||
acc_close[access_bank] <= 1'b1;
|
||||
end
|
||||
else if(clk) begin
|
||||
for(i = 0; i < 4; i = i + 1)
|
||||
if(acc_state[i] == 4'b0010)
|
||||
acc_init_callback[i] <= 1'b1;
|
||||
|
||||
if(~(acc_state[0] | acc_state[1] | acc_state[2] | acc_state[3]))
|
||||
RAM_enable <= 1'b1;
|
||||
|
||||
// Bank access management
|
||||
acc_cycles[acc_bank] <= acc_cycles[acc_bank] + 1'b1;
|
||||
if(acc_cycles[acc_bank] == {CPB{1'b1}}) begin
|
||||
|
||||
// Close banks as needed
|
||||
if(acc_close[0]) begin
|
||||
acc_close[0] <= 1'b0;
|
||||
RAM_bank_sel <= 2'b00;
|
||||
acc_state[0] <= 4'b0000;
|
||||
end
|
||||
else if(acc_close[1]) begin
|
||||
acc_close[1] <= 1'b0;
|
||||
RAM_bank_sel <= 2'b01;
|
||||
acc_state[1] <= 4'b0000;
|
||||
end
|
||||
else if(acc_close[2]) begin
|
||||
acc_close[2] <= 1'b0;
|
||||
RAM_bank_sel <= 2'b10;
|
||||
acc_state[2] <= 4'b0000;
|
||||
end
|
||||
else if(acc_close[3]) begin
|
||||
acc_close[3] <= 1'b0;
|
||||
RAM_bank_sel <= 2'b11;
|
||||
acc_state[3] <= 4'b0000;
|
||||
end
|
||||
|
||||
// Increment bank tracker
|
||||
if(~(acc_close[0] | acc_close[1] | acc_close[2] | acc_close[3])) begin
|
||||
acc_bank <= acc_bank + 1;
|
||||
acc_cycles <= {CPB{1'b0}};
|
||||
end
|
||||
else begin
|
||||
// Trigger RAM row-close event
|
||||
RAM_enable <= 1'b0;
|
||||
RAM_strobe_row <= 1'b1;
|
||||
RAM_strobe_col <= 1'b1;
|
||||
RAM_write_enable <= 1'b0;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
// Access bank
|
||||
for(i = 0; i < 4; i = i + 1) begin
|
||||
// Bank_{i} active and not closing and...
|
||||
// Enough cycles left or when no other bank is active or...
|
||||
// Bank_{i+1} at cycle limit and next banks inactive or bank is closing or...
|
||||
// Bank_{i+2} at cycle limit and next bank inactive or bank is closing or...
|
||||
// Bank_{i+3} at cycle limit or closing
|
||||
if(!acc_close[i] && acc_state[i] == 4'b0100 && (
|
||||
(acc_bank == i && (acc_cycles != {CPB{1'b1}} || (acc_state[(i+1)%4] != 4'b0100 && acc_state[(i+2)%4] != 4'b0100 && acc_state[(i+3)%4] != 4'b0100))) ||
|
||||
(acc_bank == (i+1)%4 && ((acc_close[(i+1)%4] || acc_cycles == {CPB{1'b1}}) && acc_state[(i+2)%4] != 4'b0100 && acc_state[(i+3)%4] != 4'b0100)) ||
|
||||
(acc_bank == (i+2)%4 && ((acc_close[(i+2)%4] || acc_cycles == {CPB{1'b1}}) && acc_state[(i+3)%4] != 4'b0100)) ||
|
||||
(acc_bank == (i+3)%4 && (acc_close[(i+3)%4] || acc_cycles == {CPB{1'b1}}))
|
||||
)) begin
|
||||
RAM_bank_sel <= i;
|
||||
RAM_addr <= {2'b0, RAM_addr[7:0]};
|
||||
RAM_A10 <= 1'b1;
|
||||
RAM_strobe_row <= 1'b1;
|
||||
RAM_strobe_col <= 1'b0;
|
||||
RAM_write_enable <= ~acc_type[i];
|
||||
op_bank <= i;
|
||||
event_trigger[0] <= event_trigger[1] ? 1'b0 : 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else if(acc_event) begin
|
||||
for(i = 0; i < 4; i = i + 1) begin
|
||||
if(acc_state[i] == 4'b0001) begin
|
||||
RAM_bank_sel <= i;
|
||||
RAM_strobe_row <= 1'b1;
|
||||
RAM_strobe_col <= 1'b0;
|
||||
RAM_write_enable <= ~acc_type[i];
|
||||
RAM_A10 <= 1;
|
||||
acc_state[i] <= 4'b0010;
|
||||
acc_init_callback[i] <= 1'b0;
|
||||
end
|
||||
else if(acc_state[i] == 4'b0010) begin
|
||||
acc_init_callback[i] <= 1'b0;
|
||||
acc_state[i] <= 4'b0100;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge write_rq) begin
|
||||
if(!read_init[access_bank] && !read_rq) begin
|
||||
//TODO: Implement read
|
||||
end
|
||||
end
|
||||
// Reset op_trigger by tracking posedge-driven event_trigger
|
||||
always @(negedge clk) event_trigger[1] <= event_trigger[0] ? 1'b1 : 1'b0;
|
||||
|
||||
endmodule
|
||||
|
@ -28,15 +28,17 @@ localparam PLL_SELECT = 1; // 0: 100MHz, 1: 200MHz, 2: 300MHz, 3: 400MHz,
|
||||
localparam RAM_PLL = 0; // Must be either 0 or 1. DO NOT SET TO ANY OTHER VALUE AS IT MIGHT FRY THE ONBOARD RAM!!!
|
||||
|
||||
// ---- REGISTERS ---- //
|
||||
reg debounce; // Input debouncer
|
||||
reg db_trap; // Debounce buffer
|
||||
reg [3:0] seg_buf_numbers [0:3]; // 7-segment binary-number-representation buffer
|
||||
reg [1:0] stage; // Computational stage
|
||||
reg [7:0] alu_a; // ALU (core0) input a
|
||||
reg [7:0] alu_b; // ALU (core0) input b
|
||||
reg [7:0] alu_op; // ALU (core0) opcode
|
||||
reg [2:0] gfx_rgb; // VGA color channels
|
||||
reg [1:0] ram_bank_sel; // Which ram bank to access
|
||||
reg debounce; // Input debouncer
|
||||
reg db_trap; // Debounce buffer
|
||||
reg [3:0] seg_buf_numbers [0:3];// 7-segment binary-number-representation buffer
|
||||
reg [1:0] stage; // Computational stage
|
||||
reg [7:0] alu_a; // ALU (core0) input a
|
||||
reg [7:0] alu_b; // ALU (core0) input b
|
||||
reg [7:0] alu_op; // ALU (core0) opcode
|
||||
reg [2:0] gfx_rgb; // VGA color channels
|
||||
reg [1:0] ram_bank_sel; // Which ram bank to access
|
||||
reg [11:0] ram_addr; // RAM address selection
|
||||
reg ram_close; // RAM close-row trigger
|
||||
|
||||
// ---- WIRES ---- //
|
||||
wire [7:0] seg_buf[0:3]; // Encoded segment buffer (8-bit expanded 4-bit number buffer)
|
||||
@ -48,8 +50,8 @@ wire cb; // Callback/timeout
|
||||
wire [9:0] vga_coords[0:1]; // Current screen coordinates being drawn to
|
||||
wire ram_request_read; // Trigger a read operation from main memory
|
||||
wire ram_request_write; // Trigger a write operation from main memory
|
||||
wire [3:0] ram_event; // Event trigger from ram when an operation is completed (ex. a read op is ready)
|
||||
wire [15:0] ram_state; // Main memory event information (0:3; bank0, 4:7; bank1, 8:11; bank2, 12:15; bank3)
|
||||
wire ram_event; // Event trigger from ram when a r/w operation is ready
|
||||
wire [1:0] ram_event_bank; // Which bank an event is happening on
|
||||
|
||||
// ---- WIRE ASSIGNS ---- //
|
||||
assign pll[4] = clk;
|
||||
@ -104,8 +106,10 @@ RAM main_memory(
|
||||
ram_request_read,
|
||||
ram_request_write,
|
||||
ram_bank_sel,
|
||||
ram_state,
|
||||
ram_event
|
||||
ram_event,
|
||||
ram_addr,
|
||||
ram_close,
|
||||
ram_event_bank
|
||||
);
|
||||
|
||||
always @(posedge cb or negedge value) select_out <= cb ? 4'b0000 : 4'b1111;
|
||||
|
Loading…
x
Reference in New Issue
Block a user