Initial commit

This commit is contained in:
Nikolay Puzanov
2021-02-02 19:09:52 +03:00
commit 00b07d114f
14 changed files with 4345 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
`timescale 1ns/100ps
`default_nettype none
module dual_mcp3201_pmod #(parameter CLOCK_FREQ = 25000000,
parameter SAMPLE_RATE = 50000)
(input wire clock,
input wire reset,
output wire radc_ssn,
output wire radc_clk,
input wire radc_dat,
output wire ladc_ssn,
output wire ladc_clk,
input wire ladc_dat,
output wire [11:0] rdata,
output wire rstrb,
output wire [11:0] ldata,
output wire lstrb);
localparam MCP3201_CLOCK_PER_SAMPLE = 17;
localparam SCLK_FREQ = SAMPLE_RATE * MCP3201_CLOCK_PER_SAMPLE;
logic spi_clk;
spi_sclk_gen #(.CLOCK_FREQ(CLOCK_FREQ),
.SCLK_FREQ(SCLK_FREQ)) spi_sclk_gen_impl
(.clock, .reset,
.sclk_o(spi_clk));
mcp3201 adc_left
(.clock, .reset,
.spi_clk_i(spi_clk),
.spi_ssn_o(ladc_ssn),
.spi_miso_i(ladc_dat),
.data_o(ldata),
.strb_o(lstrb));
mcp3201 adc_right
(.clock, .reset,
.spi_clk_i(spi_clk),
.spi_ssn_o(radc_ssn),
.spi_miso_i(radc_dat),
.data_o(rdata),
.strb_o(rstrb));
assign ladc_clk = spi_clk;
assign radc_clk = spi_clk;
endmodule // dual_mcp3201_pmod

77
source/mcp3201.sv Normal file
View File

@@ -0,0 +1,77 @@
`timescale 1ns/100ps
`default_nettype none
/*
* MCP3201 controller
* Make one sample per 17 clock periods.
*/
module mcp3201
(input wire clock,
input wire reset,
input wire spi_clk_i,
output reg spi_ssn_o,
input wire spi_miso_i,
output reg [11:0] data_o,
output reg strb_o);
logic sclk_posedge;
logic sclk_prev;
always_ff @(posedge clock)
if (reset) sclk_prev <= 1'b0;
else sclk_prev <= spi_clk_i;
assign sclk_posedge = { sclk_prev, spi_clk_i } == 2'b01 ? 1'b1 : 1'b0;
/* Receive data FSM */
enum int unsigned {
ST_RELAX = 0,
ST_SHIFT,
ST_STROBE
} state;
logic [3:0] bit_cnt;
logic [11:0] data_sr;
always_ff @(posedge clock)
if (reset) begin
state <= ST_RELAX;
bit_cnt <= '0;
spi_ssn_o <= 1'b1;
data_o <= '0;
strb_o <= 1'b0;
end
else begin
strb_o <= 1'b0;
case (state)
ST_RELAX:
if (sclk_posedge) begin
bit_cnt <= '0;
spi_ssn_o <= 1'b0;
state <= ST_SHIFT;
end
ST_SHIFT:
if (sclk_posedge) begin
data_sr <= { data_sr[10:0], spi_miso_i };
bit_cnt <= bit_cnt + 1'b1;
if (bit_cnt == 4'd14) begin
spi_ssn_o <= 1'b1;
state <= ST_STROBE;
end
end
ST_STROBE: begin
data_o <= data_sr;
strb_o <= 1'b1;
state <= ST_RELAX;
end
endcase
end
endmodule // mcp3201

17
source/pll_lock_reset.sv Normal file
View File

@@ -0,0 +1,17 @@
`timescale 1ns/100ps
`default_nettype none
module pll_lock_reset #(parameter RESET_LEN = 8)
(input wire pll_clock,
input wire pll_lock,
output wire reset);
logic [RESET_LEN:0] rst_sr;
always_ff @(posedge pll_clock, negedge pll_lock)
if (~pll_lock) rst_sr <= '0;
else rst_sr <= { 1'b1, rst_sr[RESET_LEN:1] };
assign reset = ~rst_sr[0];
endmodule // pll_lock_reset

34
source/spi_sclk_gen.sv Normal file
View File

@@ -0,0 +1,34 @@
`timescale 1ns/100ps
`default_nettype none
module spi_sclk_gen #(parameter CLOCK_FREQ = 12000000,
parameter SCLK_FREQ = 50000)
(input wire clock,
input wire reset,
output reg sclk_o);
localparam SCLK_PERIOD = integer'($floor(real'(CLOCK_FREQ)/real'(SCLK_FREQ) + 0.5));
localparam SCLK_HPER = SCLK_PERIOD/2;
localparam SCLK_CW = $clog2(SCLK_PERIOD);
logic [SCLK_CW-1:0] sclk_cnt;
always_ff @(posedge clock)
if (reset) begin
sclk_cnt <= '0;
sclk_o <= 1'b0;
end
else begin
if (sclk_cnt == '0)
sclk_o <= 1'b0;
else
if (sclk_cnt == SCLK_CW'(SCLK_HPER))
sclk_o <= 1'b1;
if (sclk_cnt == SCLK_CW'(SCLK_PERIOD-1))
sclk_cnt <= '0;
else
sclk_cnt <= sclk_cnt + 1'b1;
end
endmodule // spi_sclk_gen