large restructure

This commit is contained in:
2021-08-11 00:18:46 -06:00
parent 6b0a72d516
commit 392e0a24ed
25 changed files with 158 additions and 281 deletions

View File

@ -0,0 +1,91 @@
```wavedrom
{
signal: [
{name: 'ACLK', wave: 'P..|..'},
['Write Address',
{name: 'AWVALID', wave: '010|..', data: []},
{name: 'AWADDR', wave: 'x3x|..', data: [1,2,3,4]},
{name: 'AWPROT', wave: 'x3x|..', data: [1,2,3,4]},
{name: 'AWREADY', wave: '1..|..', data: []},
],
['Write Data',
{name: 'WVALID', wave: '010|..', data: []},
{name: 'WDATA', wave: 'x3x|..', data: [1,2,3,4]},
{name: 'WSTRB', wave: 'x3x|..', data: [1,2,3,4]},
{name: 'WREADY', wave: '1..|..', data: []},
],
['Write Resp',
{name: 'BVALID', wave: '0..|10', data: []},
{name: 'BREADY', wave: '01.|.0', data: []},
{name: 'BRESP', wave: 'x..|3x', data: [1,2,3,4]},
],
],
head:{
text:'AXI-Lite Write Example',
tick:0,
},
foot:{
text:'Slave may take arbitrarily long to respond',
}
}
```
```wavedrom
{
signal: [
{name: 'ACLK', wave: 'P.......'},
['Write Address',
{name: 'AWVALID', wave: '01...0..', data: []},
{name: 'AWADDR', wave: 'x345.x..', data: [1,2,3,4]},
{name: 'AWPROT', wave: 'x345.x..', data: [1,2,3,4]},
{name: 'AWREADY', wave: '1..01...', data: []},
],
['Write Data',
{name: 'WVALID', wave: '010.1.0.', data: []},
{name: 'WDATA', wave: 'x3x.45x.', data: [1,2,3,4]},
{name: 'WSTRB', wave: 'x3x.45x.', data: [1,2,3,4]},
{name: 'WREADY', wave: '1.......', data: []},
],
['Write Resp',
{name: 'BVALID', wave: '0.10.1.0', data: []},
{name: 'BREADY', wave: '01.....0', data: []},
{name: 'BRESP', wave: 'x.3x.45x', data: [1,2,3,4]},
],
],
head:{
text:'AXI-Lite Write Example',
tick:0,
}
}
```
```wavedrom
{
signal: [
{name: 'ACLK', wave: 'P.....'},
['Write Address',
{name: 'AWVALID', wave: '01..0.', data: []},
{name: 'AWADDR', wave: 'x345x.', data: [1,2,3,4]},
{name: 'AWPROT', wave: 'x345x.', data: [1,2,3,4]},
{name: 'AWREADY', wave: '1...0.', data: []},
],
['Write Data',
{name: 'WVALID', wave: '01..0.', data: []},
{name: 'WDATA', wave: 'x345x.', data: [1,2,3,4]},
{name: 'WSTRB', wave: 'x345x.', data: [1,2,3,4]},
{name: 'WREADY', wave: '1.....', data: []},
],
['Write Resp',
{name: 'BVALID', wave: '0.1..0', data: []},
{name: 'BREADY', wave: '01...0', data: []},
{name: 'BRESP', wave: 'x.345x', data: [1,2,3,4]},
],
],
head:{
text:'AXI-Lite Write Example',
tick:0,
}
}
```

View File

@ -0,0 +1,36 @@
interface axi_lite();
parameter DATA_WIDTH = 32;
parameter ADDR_WIDTH = 12;
// Global
logic ACLK;
logic ARESETn;
// Write address
logic AWVALID;
logic [ADDR_WIDTH-1:0] AWADDR;
logic [2:0] AWPROT;
logic AWREADY;
// Write data
logic WVALID;
logic [DATA_WIDTH-1:0] WDATA;
logic [(DATA_WIDTH/8)-1:0] WSTRB;
logic WREADY;
// Write response
logic BVALID;
logic BREADY;
logic [1:0] BRESP;
// Read address
logic ARVALID;
logic [ADDR_WIDTH-1:0] ARADDR;
logic [2:0] ARPROT;
logic ARREADY;
// Read data
logic RVALID;
logic [DATA_WIDTH-1:0] RDATA;
logic [1:0] RRESP;
logic RREADY;
endinterface

View File

@ -0,0 +1,152 @@
module axi_lite_memory(
// Global
input ACLK,
input ARESETn,
// Write address
input AWVALID,
input [ADDR_WIDTH-1:0] AWADDR,
input [2:0] AWPROT,
output reg AWREADY,
// Write data
input WVALID,
input [DATA_WIDTH-1:0] WDATA,
input [(DATA_WIDTH/8)-1:0] WSTRB,
output reg WREADY,
// Write response
output reg BVALID,
input BREADY,
output reg [1:0] BRESP,
// Read address
input ARVALID,
input [ADDR_WIDTH-1:0] ARADDR,
input [2:0] ARPROT, // IGNORED
output reg ARREADY,
// Read data
output reg RVALID,
output reg [DATA_WIDTH-1:0] RDATA,
output reg [1:0] RRESP,
input RREADY,
// Wishbone write
output reg [ADDR_WIDTH-1:0] WB_WADDR,
output reg [2:0] WB_WPROT,
output reg [DATA_WIDTH-1:0] WB_WDATA,
output reg [(DATA_WIDTH/8)-1:0] WB_WSTRB,
output reg WB_WVALID = 0,
input WB_WREADY,
// Wishbone read
output reg [ADDR_WIDTH-1:0] WB_RADDR,
input [DATA_WIDTH-1:0] WB_RDATA,
input WB_RVALID,
output reg WB_RREADY
);
parameter DATA_WIDTH = 32; // Only 32 allowed for now (AXI-Lite allows 32 or 64). 64 might work but I haven't investigated it yet.
parameter ADDR_WIDTH = 12; // No minimum requirement. Typically at least 12b (4KB)
parameter SYNC_DEPTH = 1; // Minimum recommended: 2. Larger synchronizer depth allows for larger delay between AXI address and data without stalling.
reg [ADDR_WIDTH-1:0] sync_awaddr [0:SYNC_DEPTH-1];
reg [2:0] sync_awprot [0:SYNC_DEPTH-1];
reg [$clog2(SYNC_DEPTH)+1:0] sync_aw_fill = 0;
reg [DATA_WIDTH-1:0] sync_wdata [0:SYNC_DEPTH-1];
reg [(DATA_WIDTH/8)-1:0] sync_wstrb [0:SYNC_DEPTH-1];
reg [$clog2(SYNC_DEPTH)+1:0] sync_w_fill = 0;
reg [1:0] sync_bresp [0:SYNC_DEPTH-1]; // TODO: make this not be the same sync_depth?
reg [$clog2(SYNC_DEPTH)+1:0] sync_b_fill = 0;
localparam RESP_OKAY = 2'b00,
RESP_EXOKAY = 2'b01,
RESP_SLVERR = 2'b10,
RESP_DECERR = 2'b11;
always @(*) begin
AWREADY = sync_aw_fill < SYNC_DEPTH;
WREADY = sync_w_fill < SYNC_DEPTH;
BRESP = RESP_OKAY; // TODO: add support for responses other than OKAY
BVALID = sync_b_fill > 0;
end
always @(posedge ACLK or negedge ARESETn) begin: clk_update
integer i;
// Write direction
integer event_wb_write;
integer event_aw;
integer event_w;
integer event_b;
// Read direction
integer event_wb_read;
integer event_ar;
integer event_r;
// Write direction
event_wb_write = 0;
event_aw = 0;
event_w = 0;
event_b = 0;
// Read direction
event_wb_read = 0;
event_ar = 0;
event_r = 0;
if (ARESETn == 0) begin
// TODO: deal with reset
sync_aw_fill <= 0;
sync_w_fill <= 0;
sync_b_fill <= 0;
end else begin
if (AWREADY && AWVALID) begin
event_aw = 1;
for (i=0; i<sync_aw_fill; i=i+1) begin
sync_awaddr[i+1] <= sync_awaddr[i];
sync_awprot[i+1] <= sync_awprot[i];
end
sync_awaddr[0] <= AWADDR;
sync_awprot[0] <= AWPROT;
end
if (WREADY && WVALID) begin
event_w = 1;
for (i=0; i<sync_w_fill; i=i+1) begin
sync_wdata[i+1] <= sync_wstrb[i];
sync_wstrb[i+1] <= sync_wstrb[i];
end
sync_wdata[sync_w_fill] <= WDATA;
sync_wstrb[sync_w_fill] <= WSTRB;
end
if (BREADY && BVALID) begin
event_b = 1;
end
if (WB_WREADY || !WB_WVALID) begin
event_wb_write = 1;
if (sync_aw_fill > 0 && sync_w_fill > 0) begin
WB_WVALID <= 1'b1;
WB_WADDR <= sync_awaddr[sync_aw_fill-1];
WB_WPROT <= sync_awprot[sync_aw_fill-1];
WB_WDATA <= sync_wdata[sync_w_fill-1];
WB_WSTRB <= sync_wstrb[sync_w_fill-1];
end else begin
WB_WVALID <= 1'b0;
end
end
sync_aw_fill <= sync_aw_fill + event_aw - event_wb_write;
sync_w_fill <= sync_w_fill + event_w - event_wb_write;
sync_b_fill <= sync_b_fill - event_b + event_wb_write; // TODO: is this right?
end
end
endmodule

View File

@ -0,0 +1,56 @@
module correlator #(
parameter LENGTH = 8,
parameter BITS_IN = 8,
parameter BITS_INTERNAL = BITS_IN + $clog2(LENGTH),
parameter BITS_OUT = 8,
)(
input wire clk,
input wire reset,
input wire [BITS_IN-1:0] a,
input wire [BITS_IN-1:0] b,
output reg [BITS_OUT-1:0] y
);
// verify parameters are valid
if (BITS_OUT > BITS_INTERNAL) begin
$error("BITS_OUT (%d) must be <= BITS_INTERNAL (%d)", BITS_OUT, BITS_INTERNAL);
end
// signals
reg [BITS_IN-1] aa [0:LENGTH-1];
reg [BITS_IN-1] bb [0:LENGTH-1];
reg [BITS_INTERNAL-1:0] sum;
// combinatorial calculation
always @(*) begin : continuous
integer i;
aa[0] = a;
bb[0] = b;
sum = 0;
for (i=0; i<LENGTH; i=i+1) begin
sum = sum + aa[i] * bb[i]
end
end
// synchronous update
always @(posedge clk or posedge reset) begin : update
integer i;
if (reset) begin
for (i=1; i<LENGTH; i=i+1) begin
aa[i] <= 0;
bb[i] <= 0;
end
y <= 0;
end else begin
for (i=1; i<LENGTH; i=i+1) begin
aa[i] <= aa[i-1];
bb[i] <= bb[i-1];
end
y <= sum[BITS_OUT-1:0];
end
end
endmodule

22
other_projects/gps.v Normal file
View File

@ -0,0 +1,22 @@
module gps #(
parameter BITS_IN,
)(
input wire clk,
input wire reset,
input [BITS_IN-1:0] in_i,
input [BITS_IN-1:0] in_q,
);
for (prn=1; prn<=32; prn=prn+1) begin
correlator #(
.BITS_IN(BITS_IN),
) cor(
.clk(clk),
.reset(reset),
.a()
);
end
endmodule

21
other_projects/test.sv Normal file
View File

@ -0,0 +1,21 @@
interface test_if();
parameter int DW = 32;
logic[DW-1:0] data;
modport consumer (
input data
);
endinterface
module test_mod(
test_if.consumer if_in,
output[31:0] dout
);
assign dout = if_in.data;
endmodule

66
other_projects/test_sv.sv Normal file
View File

@ -0,0 +1,66 @@
// `include "axi_lite_if.sv"
interface axi_lite_if();
parameter DATA_WIDTH = 32;
parameter ADDR_WIDTH = 12;
logic RREADY;
modport master (
output RREADY
);
modport slave (
// // Global
// input ACLK,
// input ARESETn,
// // Write address
// input AWVALID,
// // input [ADDR_WIDTH-1:0] AWADDR,
// // input [2:0] AWPROT,
// output AWREADY,
// // Write data
// input WVALID,
// // input [DATA_WIDTH-1:0] WDATA,
// // input [(DATA_WIDTH/8)-1:0] WSTRB,
// output WREADY,
// // Write response
// output BVALID,
// input BREADY,
// // output [1:0] BRESP,
// // Read address
// input ARVALID,
// // input [ADDR_WIDTH-1:0] ARADDR,
// // input [2:0] ARPROT,
// output ARREADY,
// // Read data
// output RVALID,
// output [DATA_WIDTH-1:0] RDATA,
// output [1:0] RRESP,
input RREADY
);
endinterface
module test_sv(
axi_lite_if.slave s_axil,
input clk,
output c, d
);
logic a, b;
assign a = clk;
always @(*) begin
b = !clk;
end
assign c = a;
assign d = b;
endmodule

98
other_projects/top.v Normal file
View File

@ -0,0 +1,98 @@
module top(
input clk50,
output [1:0] led
);
wire [31:0] mem_inst_addr;
wire [31:0] mem_inst_idx = mem_inst_addr >> 2;
reg [31:0] mem_inst_data;
reg [31:0] mem_inst [0:MEM_INST_LENGTH-1];
integer i;
localparam OP_LUI = 7'b0110111,
OP_AUIPC = 7'b0010111,
OP_JAL = 7'b1101111,
OP_JALR = 7'b1100111,
OP_BRANCH = 7'b1100011,
OP_LOAD = 7'b0000011,
OP_STORE = 7'b0100011,
OP_IMM = 7'b0010011,
OP_ALU = 7'b0110011,
OP_FENCE = 7'b0001111,
OP_SYSTEM = 7'b1110011;
localparam MEM_INST_LENGTH = 256;
localparam MEM_DATA_LENGTH = 256;
localparam INST_NOP = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd0, OP_ALU}; // nop
initial begin
for (i=0; i<MEM_INST_LENGTH; i=i+1) begin
mem_inst[i] = INST_NOP;
end
// Initialize all registers
mem_inst[0] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd1, OP_ALU}; // add x1, x0, x0
mem_inst[1] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd2, OP_ALU}; // add x2, x0, x0
mem_inst[2] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd3, OP_ALU}; // add x3, x0, x0
mem_inst[3] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd4, OP_ALU}; // add x4, x0, x0
mem_inst[4] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd5, OP_ALU}; // add x5, x0, x0
mem_inst[5] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd6, OP_ALU}; // add x6, x0, x0
mem_inst[6] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd7, OP_ALU}; // add x7, x0, x0
mem_inst[7] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd8, OP_ALU}; // add x8, x0, x0
mem_inst[8] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd9, OP_ALU}; // add x9, x0, x0
mem_inst[9] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd10, OP_ALU}; // add x10, x0, x0
mem_inst[10] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd11, OP_ALU}; // add x11, x0, x0
mem_inst[11] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd12, OP_ALU}; // add x12, x0, x0
mem_inst[12] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd13, OP_ALU}; // add x13, x0, x0
mem_inst[13] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd14, OP_ALU}; // add x14, x0, x0
mem_inst[14] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd15, OP_ALU}; // add x15, x0, x0
mem_inst[15] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd16, OP_ALU}; // add x16, x0, x0
mem_inst[16] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd17, OP_ALU}; // add x17, x0, x0
mem_inst[17] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd18, OP_ALU}; // add x18, x0, x0
mem_inst[18] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd19, OP_ALU}; // add x19, x0, x0
mem_inst[19] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd20, OP_ALU}; // add x20, x0, x0
mem_inst[20] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd21, OP_ALU}; // add x21, x0, x0
mem_inst[21] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd22, OP_ALU}; // add x22, x0, x0
mem_inst[22] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd23, OP_ALU}; // add x23, x0, x0
mem_inst[23] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd24, OP_ALU}; // add x24, x0, x0
mem_inst[24] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd25, OP_ALU}; // add x25, x0, x0
mem_inst[25] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd26, OP_ALU}; // add x26, x0, x0
mem_inst[26] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd27, OP_ALU}; // add x27, x0, x0
mem_inst[27] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd28, OP_ALU}; // add x28, x0, x0
mem_inst[28] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd29, OP_ALU}; // add x29, x0, x0
mem_inst[29] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd30, OP_ALU}; // add x30, x0, x0
mem_inst[30] = {7'b0000000, 5'd0, 5'd0, 3'b000, 5'd31, OP_ALU}; // add x31, x0, x0
mem_inst[36] = {12'd1, 5'd0, 3'b000, 5'd2, OP_IMM}; // addi x2, x0, 1
mem_inst[42] = {7'b0000000, 5'd2, 5'd1, 3'b000, 5'd3, OP_ALU}; // add x3, x1, x2
mem_inst[48] = {7'b0000000, 5'd2, 5'd3, 3'b000, 5'd3, OP_ALU}; // add x3, x3, x2
mem_inst[54] = {7'b0000000, 5'd3, 5'd3, 3'b000, 5'd3, OP_ALU}; // add x3, x3, x3
mem_inst[60] = {12'h123, 5'd0, 3'b000, 5'd4, OP_IMM}; // addi x4, x0, 0x123
mem_inst[66] = {12'hfff, 5'd4, 3'b000, 5'd5, OP_IMM}; // addi x5, x4, 0xfff
mem_inst[72] = {20'hedcba, 5'd7, OP_LUI}; // lui x7, 0xedcba
mem_inst[78] = {12'h987, 5'd7, 3'b000, 5'd7, OP_IMM}; // addi x7, x7, 0x987
mem_inst[84] = {20'h00032, 5'd8, OP_AUIPC}; // auipc x8, 0x32 // 84*4 + 0x32 = 0x182
end
always @(*) begin
if (mem_inst_idx < MEM_INST_LENGTH) begin
mem_inst_data = mem_inst[mem_inst_idx];
end else begin
mem_inst_data = INST_NOP;
end
end
core c(
.clk(clk50),
.reset(1'b0),
.dummy_out(led[0]),
.mem_inst_addr(mem_inst_addr),
.mem_inst_data(mem_inst_data)
);
assign led[1] = mem_inst_addr[1];
endmodule